以下代码中的覆盖如何工作?

Posted

技术标签:

【中文标题】以下代码中的覆盖如何工作?【英文标题】:how overriding works in the following code? 【发布时间】:2014-01-08 21:13:53 【问题描述】:

考虑下面的java代码:

public class Superclass     
    public void printMethod() 
        System.out.println("Printed in Superclass.");
    

这是一个子类,称为 Subclass,它覆盖了 printMethod():

public class Subclass extends Superclass     
    // overrides printMethod in Superclass
    public void printMethod() 
        super.printMethod();
        System.out.println("Printed in Subclass");
    
    public static void main(String[] args) 
        Subclass s = new Subclass();
        s.printMethod();    
    

得到的输出如下:

Printed in Superclass
Printed in Subclass

如果子类被覆盖,为什么超类println 仍然显示在屏幕上? 不只是在子类上显示方法的内容吗?

如果方法被覆盖,为什么在下面的代码中不调用 super?

@Override
public boolean onCreateOptionsMenu(Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;

【问题讨论】:

你认为super.printMethod(); 会做什么? 【参考方案1】:

1因为方法super.printMethod();的第一行

2因为没有调用super 方法。

【讨论】:

【参考方案2】:

如果子类被覆盖,为什么超类 println 仍然显示在屏幕上?

因为你打电话给super.printMethod()。这调用了printMethod() 的父类实现。

如果方法被覆盖,为什么在下面的代码中没有调用 super?

因为开发人员不需要或不希望父类中的代码执行 - 他想完全重写该方法。您可能还会看到在未定义父实现时使用override 关键字,例如使用接口或抽象类。

不需要调用方法的父类实现。

【讨论】:

【参考方案3】:

如果子类被覆盖,为什么超类 println 仍然存在 显示在屏幕上?它不只是假设显示的内容 子类的方法?

这一行:

super.printMethod();

将调用super 类的printMethod()。这基本上会变成:

new Superclass().printmethod();

您不需要调用 super 来进行覆盖。改为这样做:

// overrides printMethod in Superclass
public void printMethod() 
    //super.printMethod();
    System.out.println("Printed in Subclass");

解决您的问题的另一种方法是执行以下操作:

public class Superclass     
    public void printMethod() 
        System.out.println("Printed in " + this.getClass().getName() + ".");
    

那就这样吧:

public class Subclass extends Superclass     
    // overrides printMethod in Superclass
    public void printMethod() 
        super.printMethod();//just do override
    
    public static void main(String[] args) 
        Subclass s = new Subclass();
        s.printMethod();    
    

另一个问题,为什么在下面的代码中没有调用 super 如果方法被覆盖?

如上所述,您不需要super 来执行@Override。来自this question:

每次重写方法时使用它有两个好处。这样做 您可以利用编译器检查来确保您 当您认为自己是时,实际上正在覆盖一种方法。这样,如果 你犯了一个常见的错误拼写方法名称 正确匹配参数,您将被警告您的方法 实际上并没有像您认为的那样覆盖。其次,它使 您的代码更容易理解,因为方法更明显 被覆盖。

此外,在 Java 1.6 中,您可以使用它来标记方法何时 实现一个接口以获得相同的好处。我想会是 最好有一个单独的注释(如@Implements),但它 总比没有好。

如果您想了解更多关于何时将super方法覆盖 一起使用,那么check this article question.

【讨论】:

如果我理解正确,如果你删除了 super 那么你就没有调用 super 的 printMethod();对?那么为什么在这种情况下覆盖有用呢?我可以创建 2 个不扩展任何东西的类,它们都有一个打印语句。 根据您的设计,覆盖方法很有用。我已经更新了你为什么使用@Override的答案。 @user3170491 你还不了解 OOP,是吗?答案是多态性。对于简单的程序,当然可以。但在更高层次上,组织代码以适应接口是有益的,这样它就可以是多功能和模块化的。【参考方案4】:

您不必使用super.printMethod(); 调用超类方法来覆盖该方法,但是您这样做了,所以

Printed in Superclass

已打印。要不打印,请删除对super.printMethod(); 的调用;没必要。

对于onCreateOptionsMenu,它没有使用被覆盖的功能,所以不需要调用super.onCreateOptionsMenu

【讨论】:

【参考方案5】:

当你调用 super() 时,你调用了超类的方法。如果您只是删除了 super() 调用,则覆盖仍然可以在不打印“在超类中打印”的情况下工作。

【讨论】:

以上是关于以下代码中的覆盖如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Databrick/PySpark 覆盖/更新 Azure Cosmos DB 中的集合

Angular 6 代码覆盖率...如何在应用程序的代码覆盖率中排除本地库?

如何仅覆盖一个属性:Qt StyleSheet 中的值对

Jacoco Gradle 中的最小代码覆盖率阈值

如何识别Java字节码中的覆盖方法?

iOS 项目中的 Firebase 导致代码覆盖率下降