Java继承常见困惑:间接子类赋值与引用、对象类型差异
问题解答
首先看你给出的代码:
class A { public void m() { System.out.println("A.m"); } public void n() { System.out.println("A.n"); } } class B extends A { @Override public void n() { System.out.println("B.n"); } public void p() { System.out.println("B.p"); } } class C extends A { @Override public void m() { System.out.println("C.m"); } } class D extends C { @Override public void m() { System.out.println("D.m"); } @Override public void n() { System.out.println("D.n"); } public void p() { System.out.println("D.p"); } } public class Main { public static void main(String[] args) { A a = new D(); a.m(); } }
为什么A a = new D();不会报错?
Java的继承具备传递性:D直接继承自C,而C又继承自A,所以D相当于间接继承了A,属于A的子类型。Java允许用父类(包括间接父类)的引用指向子类的实例,这是多态特性的基础——因为D本质上也是一种A,完全符合A的类型定义,编译器会认可这种向上转型的写法。
对象类型(Object type)与引用类型(Reference type)的区别
- 引用类型:指的是变量声明时的类型,比如
A a里的A。它是编译时生效的类型,决定了这个变量能调用哪些方法(编译器会做检查,比如a只能调用A类中定义的m()和n(),不能直接调用D类独有的p())。 - 对象类型:是通过
new创建出来的对象的真实类型,比如new D()里的D。它是运行时生效的类型,决定了调用方法时实际执行的是哪个版本的代码(比如a.m()实际执行的是D类重写后的m()方法,这就是动态绑定机制)。
内容的提问来源于stack exchange,提问作者quys
相关产品推荐
相关产品推荐

