Java引用类型与实例类型不匹配的三类问题解惑及资料推荐
Java类型与多态问题解析
示例代码
Bicycle类
public class Bicycle { // Bicycle类有三个成员变量 public int cadence; public int gear; public int speed; // Bicycle类的构造方法 public Bicycle(int startCadence, int startSpeed, int startGear) { gear = startGear; cadence = startCadence; speed = startSpeed; } public void printDescription(){ System.out.println("\nBike is " + "in gear " + this.gear + " with a cadence of " + this.cadence + " and travelling at a speed of " + this.speed + ". "); } }
MountainBike类
public class MountainBike extends Bicycle { private String suspension; public MountainBike( int startCadence, int startSpeed, int startGear, String suspensionType){ super(startCadence, startSpeed, startGear); this.setSuspension(suspensionType); } public void setSuspension(String suspensionType) { this.suspension = suspensionType; } public void printDescription() { super.printDescription(); System.out.println("The " + "MountainBike has a" + getSuspension() + " suspension."); } }
Main类
public class Main { public static void main(String args[]){ Object obj = new MountainBike(1,2,3,"soft"); System.out.println(obj.getClass()); // ① Q1 System.out.println(obj.getClass().getSimpleName()); obj.printDescription(); // ② Q2 ((Bicycle) obj).printDescription(); // ③ Q3 } }
运行结果与编译错误
控制台输出(Q1、Q3执行结果)
class MountainBike
MountainBike
Bike is in gear 3 with a cadence of 1 and travelling at a speed of 2.
The MountainBike has asoft suspension.
Q2编译错误
Cannot resolve method 'printDescription' in 'Object'
疑问解答
① Q1:obj变量声明为Object类型,但getClass()返回MountainBike类,原因是什么?
getClass()方法返回的是对象运行时的实际类型,和变量的声明类型无关。这里obj虽然声明为Object,但实际指向的是new MountainBike(...)创建的实例,所以getClass()会返回MountainBike的Class对象。
② Q2:obj实际指向MountainBike实例,为何直接调用printDescription()会编译报错?
Java的方法调用会先做编译时检查,编译器只认变量的声明类型。obj的声明类型是Object,而Object类中并没有printDescription()方法,所以编译器直接报错,不会管运行时实际指向的对象是什么类型。
③ Q3:将obj强制转换为Bicycle类型后,为何执行的是MountainBike的printDescription()方法?
这是Java的**多态(动态绑定)**特性:当调用一个重写的实例方法时,JVM会根据对象运行时的实际类型来决定执行哪个版本的方法。虽然把obj强转为Bicycle类型,但它实际指向的还是MountainBike实例,而MountainBike重写了printDescription()方法,所以最终执行的是子类的实现。
知识盲区总结
- 变量的编译时类型(声明类型)与运行时类型(实际指向对象的类型)的区别
- Java方法调用的编译检查规则
- 多态(动态绑定)的原理与应用场景
推荐学习资料
- Java官方文档的面向对象编程章节,重点学习类、继承、多态相关内容
- 《Java核心技术 卷I:基础知识》中面向对象编程部分,深入理解编译时与运行时类型、多态机制
内容的提问来源于stack exchange,提问作者Hooni
相关产品推荐
相关产品推荐

