当分配给子类对象的超类引用调用覆盖方法时会发生什么?
What does it happen when a superclass reference which is assigned to an object of subclass invokes an overriding method?
代码如下:
class Override {
public static void main(String[] args) {
A a = new A(1, 2);
A a1 = new B(1, 2, 3);
B b = new B(4, 5, 6);
a.show();
a1.show();
b.show();
}
}
class A {
int a;
int b;
A(int a, int b) {
this.a = a;
this.b = b;
}
void show() {
System.out.println(a + " " + b);
}
}
class B extends A {
int c;
B(int a, int b, int c) {
super(a, b);
this.c = c;
}
void show() {
System.out.println(c);
}
}
结果:
1 2
3
6
超类的引用变量可以分配给从该超类派生的任何子类的对象。
引用变量的类型决定了哪些成员可以访问。
基于以上事实,a1无法访问c(B的成员),因为a1不知道B中任何成员的存在。我的问题是当a1调用show()时,为什么调用 B 中的 show() 而不是 A 中的 show()?
感谢大家的回答。
下面是我觉得很有趣的东西:
动态方法分派 是一种在运行 时解决对覆盖方法的调用的机制。
当通过超类引用调用重写方法时,java 根据调用发生时所引用对象的类型确定要执行的方法版本。
因为 B
覆盖了方法 show()
,所以 B
中的 show()
被调用。考虑一个 abstract
方法,如果 B
不能替换它永远无法实现的抽象方法(与接口一样)。
abstract void show();
最后,如果该方法不应被重写,请将其设为 private
。默认的访问级别是继承的。
因为您的 class B
覆盖了 show()
方法。超类方法仅在继承者不覆盖它时使用。
将调用 B 中的函数。
这种机制称为 "Virtual Functions"。
如果 subclass 覆盖基 class 中的函数,程序将在 运行 时间搜索正确的函数并为正确的类型(B 而不是 A)调用它。
在 Java 中,所有函数都是虚拟的。
但是你的问题是对的,但是,在 C++ 和 C# 中,默认情况下函数不是虚拟的,如果它们没有明确声明为虚拟的,将调用 A 中的函数(在等效的 C++/C# 代码中) ;
代码如下:
class Override {
public static void main(String[] args) {
A a = new A(1, 2);
A a1 = new B(1, 2, 3);
B b = new B(4, 5, 6);
a.show();
a1.show();
b.show();
}
}
class A {
int a;
int b;
A(int a, int b) {
this.a = a;
this.b = b;
}
void show() {
System.out.println(a + " " + b);
}
}
class B extends A {
int c;
B(int a, int b, int c) {
super(a, b);
this.c = c;
}
void show() {
System.out.println(c);
}
}
结果:
1 2
3
6
超类的引用变量可以分配给从该超类派生的任何子类的对象。 引用变量的类型决定了哪些成员可以访问。
基于以上事实,a1无法访问c(B的成员),因为a1不知道B中任何成员的存在。我的问题是当a1调用show()时,为什么调用 B 中的 show() 而不是 A 中的 show()?
感谢大家的回答。
下面是我觉得很有趣的东西:
动态方法分派 是一种在运行 时解决对覆盖方法的调用的机制。 当通过超类引用调用重写方法时,java 根据调用发生时所引用对象的类型确定要执行的方法版本。
因为 B
覆盖了方法 show()
,所以 B
中的 show()
被调用。考虑一个 abstract
方法,如果 B
不能替换它永远无法实现的抽象方法(与接口一样)。
abstract void show();
最后,如果该方法不应被重写,请将其设为 private
。默认的访问级别是继承的。
因为您的 class B
覆盖了 show()
方法。超类方法仅在继承者不覆盖它时使用。
将调用 B 中的函数。 这种机制称为 "Virtual Functions"。 如果 subclass 覆盖基 class 中的函数,程序将在 运行 时间搜索正确的函数并为正确的类型(B 而不是 A)调用它。 在 Java 中,所有函数都是虚拟的。
但是你的问题是对的,但是,在 C++ 和 C# 中,默认情况下函数不是虚拟的,如果它们没有明确声明为虚拟的,将调用 A 中的函数(在等效的 C++/C# 代码中) ;