我有一个init方法,该方法被广泛继承和覆盖。然而每个init调用都会延伸到先前工作的基础上。因此,我会:
@Override public void init() {
super.init();
}
当然,这将确保调用和实例化所有内容。我的疑问是:我能创建一种方法来确保已调用超级方法吗?如果没有调用所有的init,对象就会崩溃,因此如果有人忘记调用super
,我想抛出异常或错误。
TYFT ~Aedon
我有一个init方法,该方法被广泛继承和覆盖。然而每个init调用都会延伸到先前工作的基础上。因此,我会:
@Override public void init() {
super.init();
}
当然,这将确保调用和实例化所有内容。我的疑问是:我能创建一种方法来确保已调用超级方法吗?如果没有调用所有的init,对象就会崩溃,因此如果有人忘记调用super
,我想抛出异常或错误。
TYFT ~Aedon
不要试图这样做 - 我认为这是不可行的! - 要不尝试另一种方法:
abstract class Base {
public final void baseFunction() {
...
overridenFunction(); //call the function in your base class
...
}
public abstract void overridenFunction();
}
...
class Child extends Base {
public void overridenFunction() {...};
}
...
Base object = new Child();
object.baseFunction(); //this now calls your base class function and the overridenFunction in the child class!
这个方案是否适合你?
class Grandchild extends Child
,那么您不能保证Grandchild.overridenFunction
调用Child.overridenFunction
。 - Ted HoppClass
调用foo
,那么ChildClass
会覆盖foo
并且无法调用super.foo
,当GrandChildClass
尝试调用super.foo
时,就会出现层次结构上的问题。这就是我要阻止的。 - ahodderinit()
和 childInit()
这样的不同方法名称可能有助于更好地传达意图。 - matt bpublic class Base {
private boolean called;
public Base() { // Doesn't have to be the c'tor; works elsewhere as well.
// In fact, shouldn't call overridable methods from c'tor.
called = false;
init();
if (!called) {
// throw an exception
}
}
protected void init() {
called = true;
// other stuff
}
}
实际上,Android 是通过 Activity
类来实现这一点的。我不确定他们是否需要在运行时中构建支持,但我建议查看 Activity
类的开源代码实现。具体来说,在任何生命周期方法中,您必须在执行任何操作之前调用相应的父类方法,否则它会抛出 SuperNotCalledException
异常。
例如,在 onCreate()
中,您首先必须调用 super.onCreate()
。
我经常喜欢使用这个解决方案。它不会抛出运行时错误,但会显示语法错误:
@CallSuper
public void init() {
// do stuff
}
base
的子元素都应包含以下初始化代码:super.init()
if (!_baseIsInitialized) {
// throw exception or do w/e you wish
}
基础使用在哪里
_baseIsInitialized = true;
super.init()
会更加困难,并且很可能包含丑陋的黑客技巧。child.init
进行标记化后,请检查它是否包含super.init()
,如果没有,则抛出错误”。 - orlp我不知道有什么方法可以使用一个方法来实现这个。
然而,请注意这正是构造函数的工作方式。每个构造函数必须直接或间接地调用其超类的构造函数。这是静态保证的。
我注意到你正在编写一个init方法。你能否重构代码,使其使用构造函数而不是init方法?这将使你立即获得这种行为。有些人(比如我)更喜欢构造函数而不是init方法,部分原因就在于此。
请注意,使用构造函数而不是init方法可能并不意味着在当前查看的类上使用它们 - 可能会进行重构,将需要初始化状态移动到一个平行的类层次结构中,该层次结构可以使用适当的构造函数。
现在你可以使用@CallSuper
注解你的方法。这将进行Lint检查,以确保对该方法的任何重写都调用了super()。以下是一个示例:
@CallSuper
protected void onAfterAttached(Activity activity) {
if (activity instanceof ActivityMain) {
mainActivity = (ActivityMain) activity;
}
}