父类引用对象引用子类对象--多态

发布时间 2023-12-20 22:43:40作者: DawnTraveler

在Java中,父类引用对象调用子类对象的原理涉及到两个关键概念:编译时类型和运行时类型。

  1. 编译时类型(Compile-time Type):

    • 编译时类型是指在编写代码时,你所声明的引用的类型。例如,如果你有一个声明为Animal animal的引用,编译时类型就是Animal
  2. 运行时类型(Runtime Type):

    • 运行时类型是指在程序运行时实际指向的对象的类型。如果在运行时,animal引用实际上指向了一个Dog对象,那么运行时类型就是Dog

Java中的多态性允许你使用父类的引用来引用子类的对象。这意味着,你可以将一个子类的对象分配给一个父类的引用,然后通过这个父类的引用调用在父类和子类中都存在的方法。

示例代码:

class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }

    public void fetch() {
        System.out.println("Dog fetches a ball");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 编译时类型是Animal,运行时类型是Dog
        animal.sound(); // 调用的是Dog类的sound方法,输出 "Dog barks"
        
        // 下面的代码无法通过编译,因为编译时类型是Animal,编译器只知道Animal类的方法
        // animal.fetch(); // 编译错误

        // 若要调用子类特有的方法,需要将引用强制转换为子类类型
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.fetch(); // 可以调用Dog类的fetch方法
        }
    }
}

总的来说,Java的多态性允许你在编写代码时使用通用的父类引用,然后在运行时实际指向子类对象,这样你可以在不知道对象的具体类型的情况下调用相同的方法。当然,要注意在使用时确保引用的运行时类型是正确的,否则可能会引发ClassCastException