Java 超类是否不调用重写的方法?
我有以下课程:Java 超类是否不调用重写的方法?,java,oop,polymorphism,overriding,Java,Oop,Polymorphism,Overriding,我有以下课程: class foo { public void a() { print("a"); } public void b() { a(); } } class bar extends foo { public void a() { print("overwritten a"); } } 现在调用bar.b()时,我希望它调用foo中被重写的方法a()。但是,它会打印“a” 当我运行以下命
class foo {
public void a() {
print("a");
}
public void b() {
a();
}
}
class bar extends foo {
public void a() {
print("overwritten a");
}
}
现在调用bar.b()时,我希望它调用foo中被重写的方法a()。但是,它会打印“a” 当我运行以下命令时:
public class Program {
public static void main(String[] args) {
bar b = new bar();
b.b();
}
}
class foo {
public void a() {
System.out.printf("a");
}
public void b() {
a();
}
}
class bar extends foo {
public void a() {
System.out.printf("overwritten a");
}
}
我得到以下输出:
overwritten a
这就是我希望看到的。这些方法是被定义为静态的吗?这是我唯一能看到的结果。我在这里找到了一个很好的解释:可能是您试图使用静态方法,因为它们不会被重写,所以无法工作
一种很好的检查方法是将@Override注释添加到bar.A()中,并查看编译器是否会给您一个错误,即A()实际上并没有覆盖任何内容如果您来自C#或其他语言,您可能会感到困惑,因为您必须显式声明虚拟函数和/或重写函数 在Java中,所有实例函数都是虚拟的,并且可以被重写——除非它们被声明为private和/或final 无需指定新的@Override注释即可执行此操作,添加注释只需指定您的意图是重写,如果不是重写,则会导致警告或错误。(例如,如果您意外拼错了方法名)
Andrew的示例说明了这应该如何工作。您的两个类在不同的包中吗?您的foo类方法是声明为public、protected、private还是package local?显然,如果他们是私人的,这是行不通的。可能不太明显的是,如果它们是包本地的(即没有公共/受保护/私有作用域),那么您只能在与原始类位于同一个包中时重写它们 例如: package original; public class Foo { void a() { System.out.println("A"); } public void b() { a(); } } package another; public class Bar extends original.Foo { void a() { System.out.println("Overwritten A"); } } package another; public class Program { public static void main(String[] args) { Bar bar = new Bar(); bar.b(); } } 包装原件; 公开课Foo{ void a(){System.out.println(“a”);} 公共无效b(){a();} } 包装另一个; 公共类栏扩展了original.Foo{ void a(){System.out.println(“覆盖a”);} } 包装另一个; 公共课程{ 公共静态void main(字符串[]args){ 条形=新条形(); bar.b(); } }
在这种情况下,您仍然会得到“A”。如果您在Foo public或protected中声明原始的a()方法,您将得到预期的结果。来自马口铁: “被调用的重写方法的版本是子类中的版本。被调用的隐藏方法的版本取决于它是从超类调用还是从子类调用。”
因此,如果它们都是静态方法,并且您从超类调用该方法,那么将调用超类方法,而不是子类方法。所以,实际上,没有发生重写。当我在一个Android程序上工作时,我的Java类也遇到了同样的问题。事实证明,问题不在于类,而在于Android框架处理屏幕输出的方式 例如,如果输出是在父类的onCreate()方法中编程的,则Android无法从第一个子类以外的子类中正确获取重写方法的输出。老实说,我不明白调用订单的整个方法
为了解决这个问题,我只需在onResume()中对输出进行编程,现在它似乎工作正常 你赢了我一分钟。我得到了同样的输出。也许他在发帖方面打败了你,否则,我相信,我们在发帖之前就得到了这个输出。请原谅这个教训:它被称为“覆盖”,而不是“覆盖”。您所编写的代码应该如您所期望的那样工作-正如下面的许多答案所建议的那样,要获得您正在获得的结果,您必须在代码中执行一些您没有在此处显示的其他操作。这是我的问题;将supertype方法更改为protected修复了它。我不明白的是,为什么subtype方法上的@Override标记没有让编译器在无法工作时给我一条错误消息。