【问题标题】:how do I know when/where to invoke the overridden method of the super class我怎么知道何时/何地调用超类的重写方法
【发布时间】:2023-03-18 23:55:01
【问题描述】:

我在编写 Android 应用程序时遇到了这个问题, 但这似乎是一个通用的编程问题。

情况是,我正在从库中扩展(子类化)一个类,并覆盖一个方法。我怎么知道我是否应该调用超类的方法?什么时候? (在被覆盖方法的开头还是结尾?)

例如,我在 Android 平台的“Activity”类中重写了“public boolean onCreateOptionsMenu(Menu menu)”方法。我看到有人在方法的末尾写了“return super.onCreateOptionsMenu(menu)”,举个例子。但是我怎么知道应该这样做呢?它是否正确?如果我以“super.onCreateOptionsMenu(menu)”开始我的方法有什么区别?

BR, 亨利

【问题讨论】:

    标签: java android


    【解决方案1】:

    我认为您无法抽象地回答这个问题:这取决于您要覆盖的超类方法的行为。

    视情况而定,可能适合:

    • 先调用 super
    • 最后调用超级
    • 自己处理一些案例(自定义),其余的调用 super
    • 永远不要叫 super

    希望您要覆盖的特定类的文档会告诉您是否/何时需要调用 super。

    【讨论】:

    • 除了文档,一些常识和经验也会在这里指导您。例如,除了通常发生的事情(调用超类方法)之外,您还尝试做一些事情,还是尝试做一些事情而不是正常行为(不要)?你的事情需要先发生还是可以在最后发生。
    【解决方案2】:

    不幸的是,这没有规则。你需要参考 API 文档,如果文档说你需要调用 super。

    在 Android 的情况下您是否可能需要这样做的一个提示是,您要覆盖的方法是否是生命周期方法之一。在这种情况下,您可以相当确定需要调用 super。

    【讨论】:

      【解决方案3】:

      这些都是有效的问题,但很遗憾,这里没有可遵循的一般规则。

      你是否需要调用超级方法取决于超级方法是否做了一些需要做的事情。换句话说:您是在扩展还是替换被覆盖的方法?一个好的类 API 文档应该会给你答案。此外,库通常遵循一些约定以明确如何使用它们。

      在哪里放置超级调用这个问题的答案取决于您何时想要执行您的扩展。它需要在 super 方法之前还是之后运行?大多数情况下,你首先调用 super,然后做一些额外的事情。但是,如果您需要为 super 方法准备一些东西,例如修改某些对象状态或操作参数,则将代码放在 super 调用之前。同样,API 文档应该在这里给你答案。

      【讨论】:

        【解决方案4】:

        如果您忘记调用 super,Android 在大多数情况下都会引发异常。 我相信如果你不这样做并且它不会抛出,你就不必打电话给 super。

        在 google 小组讨论中,一些生命周期方法演变的最佳实践(它们没有正式的数据支持,但被许多程序员使用):

        • 如果您处于创建方法中,例如 onCreate、onResume等调用super 作为第一个声明。因此,您可以确定必须从超类中准备的所有内容都已准备好。
        • 如果你在像 onSaveInstanceState 这样的关闭方法中,onPause 最后调用 super。现在,您可以确定在完成所有操作之前没有任何内容被删除或更改为不良状态。

        【讨论】:

          【解决方案5】:

          你不需要调用super.method(),你只在你需要它的地方调用它。

          【讨论】:

            【解决方案6】:

            当您覆盖子类中的方法时,它取决于您调用该方法的实例的类型。

            例如:

               Class Animal{
                    public eat(){
                       //..
                    }
               }
            
               Class Dog extends Animal{
                    public eat(){
                       //..
                    }
              }
            
            now if you say new Dog().eat() 
            it executes Dog's eat method.
            
            if you say new Animal().eat()
            it executes Animal's eat method.
            

            你可能有这样的代码

                   Animal a = new Dog();
                   a.eat();
            

            它再次执行 Dog 的 eat 方法,因为实际实例是 Dog 类型。

            【讨论】:

            • 我认为问题不在于调用哪个方法,而在于如何决定是否/在何处调用覆盖方法中的超类方法。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-06-11
            • 2021-09-05
            • 2010-10-18
            • 2023-03-29
            • 1970-01-01
            • 1970-01-01
            • 2021-12-08
            相关资源
            最近更新 更多