以下代码中的覆盖如何工作?
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 中的集合