16

在许多 Android 方法中,尤其是构造函数和重写方法中,您应该甚至必须使用super()调用父类方法。当您使用 Eclipse Source > Override/Implement Methods...时,您会从带有 TODO 标记的模板中获取代码,如下所示:

public MyCanvas(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}


@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub      
    super.onDraw(canvas);
} 

我不完全理解超类在每种情况下的作用,所以我总是将我的代码插入到//TODO标记的确切位置。在示例中,我将在构造函数中的代码之前和 onDraw() 中的代码之后调用 super()。

我可以始终依赖生成代码中的这些代码插入位置吗?何时调用 super() 是否有简单的规则/解释?

4

3 回答 3

15

这是一个很好的问题。不幸的是,这没有简单的规则。你需要知道超类的实现是做什么的。有时(如 中View.onDraw()),超类实现什么也不做;调用 super() 既无害又不必要。在其他情况下(例如Activity.onCreate()),超类实现执行必须在子类处理中的某个点执行的关键操作。有时调用 super() 时发生的事情应该在子类中的任何处理之前发生,有时在其他点。有时您想用您自己的处理完全替换超类处理,在这种情况下您根本不调用 super()。您可以完全自由地在子类逻辑中的任何点(甚至在多个点)调用超类版本。

在构造函数中,对超类构造函数(如果存在)的调用必须是方法中的第一件事。如果没有,编译器会自动在超类中插入对无参数构造函数的调用。(如果超类没有无参数构造函数,或者子类无法访问它,编译器会产生错误。)

如果文档没有提供足够的信息,那么您必须查看源代码。Android 代码可在此处获得(Gingerbread 版本)。API 代码位于core.

编辑git.kernel.org 上不再提供代码。这里还有另外两个可以浏览代码的地方:

主要代码在存储库 Platform > Frameworks > Base

于 2011-02-14T17:21:56.333 回答
3

我可以始终依赖生成代码中的这些代码插入位置吗?

不,有时您不想调用super.method. 有时你想首先调用它,有时在最后一个地方等等。这取决于。但是,我说的是方法,而不是构造函数。

何时调用 super() 是否有简单的规则/解释?

您将始终将所有super作为以前的答案点。唯一不调用 super 的情况是超类的构造函数没有参数;在这种情况下,编译器会super为你放置。

我不完全理解超类在每种情况下的作用,所以我总是将我的代码插入到 //TODO 标记的确切位置

如果您有疑问(我说的是超级方法),您可以随时查看源代码。谷歌代码搜索是一个很好的资源。然后你可以决定是把你的代码放在 super 方法之前还是之后;甚至,根本不要使用 super 方法。

请记住,不放置 super 方法在编译时是有效的。但是,android 上的某些方法将无法工作,除非您调用 super 方法(例如,类的onResume方法Activity)。

此外,有时您会决定是否在运行时运行超级方法。考虑这个经典的例子:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if( KeyEvent.KEYCODE_BACK == event.getKeyCode() ){
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

如果用户按下后退键,您将不会调用 super 方法。如果用户没有,则将工作委托给 super 方法。

于 2011-02-14T17:14:10.533 回答