
本文深入探讨java中对象类型与引用类型在多态性中的交互。通过实例解析,阐明编译时类型与运行时类型的区别,解释向上转型后方法调用的规则,以及方法重写如何影响实际执行。文章强调了类型转换的必要性和@override注解的最佳实践,旨在提升对java面向对象特性的理解。
在Java编程中,当我们声明一个引用变量并为其赋值时,会涉及到两个核心概念:编译时类型(Compile-time Type)和运行时类型(Runtime Type)。编译时类型是指声明变量时所使用的类型,而运行时类型则是该引用实际指向的对象的类型。理解这两者之间的区别是掌握Java多态性的基础。
考虑以下类结构及示例代码:
// 父类:Bicycle
public class Bicycle {
    public int cadence;
    public int gear;
    public int speed;
    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,继承自Bicycle
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;
    }
    // 重写父类的printDescription方法
    @Override 
    public void printDescription() {
        super.printDescription(); // 调用父类的printDescription方法
        System.out.println("The " + "MountainBike has a" +
                getSuspension() + " suspension.");
    }
    public String getSuspension() {
        return suspension;
    }
}// 主程序类:Main
public class Main {
    public static void main(String args[]){
        Object obj = new MountainBike(1,2,3,"soft"); // 向上转型
        System.out.println(obj.getClass());          // 输出运行时类型
        System.out.println(obj.getClass().getSimpleName());
    }
}在Main类的main方法中,Object obj = new MountainBike(1,2,3,"soft"); 这行代码展示了向上转型(Upcasting)。
这表明,一个对象的实际类型并不会因为被赋值给一个父类引用而改变,它始终保持着创建时的具体类型。
立即学习“Java免费学习笔记(深入)”;
理解了编译时类型和运行时类型后,我们就能深入解析方法调用的行为。
在Java中,一个引用变量能够调用哪些方法,是由其编译时类型决定的。如果尝试调用一个在编译时类型中不存在的方法,编译器将报错。
例如,如果在上述Main类的main方法中直接调用obj.printDescription():
public class Main {
    public static void main(String args[]){
        Object obj = new MountainBike(1,2,3,"soft");
        // obj.printDescription(); // 这行代码会引发编译错误
        // 错误信息:Cannot resolve method 'printDescription' in 'Object'
    }
}尽管obj的运行时类型是MountainBike,并且MountainBike类中确实有printDescription()方法,但由于obj的编译时类型是Object,而Object类中没有printDescription()方法,编译器会报错。这是因为编译器在编译阶段无法确定obj实际指向的对象类型,为了保证类型安全,它只允许调用Object类型中定义的方法。
然而,当一个方法被成功调用时(即该方法在编译时类型中存在),实际执行哪个方法版本,则是由对象的运行时类型决定的,这称为动态方法分派(Dynamic Method Dispatch)。如果子类重写了父类的方法,那么在运行时将调用实际对象类型(运行时类型)中重写的方法。
继续看Main类的示例:
public class Main {
    public static void main(String args[]){
        Object obj = new MountainBike(1,2,3,"soft");
        ((Bicycle) obj).printDescription(); // 显式向下转型为Bicycle
    }
}在这里,obj首先被强制类型转换为Bicycle类型。此时,表达式((Bicycle) obj)的编译时类型变成了Bicycle。因为Bicycle类中声明了printDescription()方法,所以编译器允许这个调用。
在运行时,尽管引用变量的编译时类型是Bicycle,但由于obj实际指向的是一个MountainBike对象,并且MountainBike类重写了printDescription()方法,Java的动态分派机制会确保调用MountainBike类中的printDescription()方法。这就是为什么控制台输出结果会包含“The MountainBike has a soft suspension.”,而不是仅仅Bicycle的描述。
Console Result: 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.
当子类需要提供父类某个方法的特定实现时,就进行方法重写。重写方法必须与父类方法有相同的名称、参数列表和返回类型(或其子类型)。
在重写父类方法时,强烈建议使用@@Override注解。
public class MountainBike extends Bicycle {
    // ...
    @Override // 明确表示这是一个重写方法
    public void printDescription() {
        super.printDescription(); // 调用父类的实现
        System.out.println("The " + "MountainBike has a" +
                getSuspension() + " suspension.");
    }
    // ...
}@Override注解本身并不会改变方法的行为,但它具有以下重要作用:
以上就是Java中对象类型与引用类型的动态行为解析的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号