欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java——向上转型和动态绑定机制

程序员文章站 2024-03-21 19:16:04
...

向上转型

向上转型即父类引用指向子类实例,也就是子类的对象可以赋值给父类的对象,又叫自动转型、隐式转型
如:Animal cat = new Cat() // Dog类是Animal类的子类
向上转型是安全的,因为任何子类都继承并接受了父类的方法。我们都知道所有的猫咪都是动物,但是向下转型就不行了,如果说所有的动物都是猫咪就不成立了(向下转型要通过强制类型转换,详细可见 Java——向下转型和instanceof 运算符的应用

父类Animal:

public class Animal {
    private String name;
    private int month;

    public Animal() {
    }

    public void eat() {
        System.out.println("动物都会吃东西");
    }

    public static void drink() {
        System.out.println("动物都必须喝水");
    }
}

子类Cat:

public class Cat extends Animal {
    private double weight;

    public Cat() {
    }

    public void eat() {
        System.out.println("猫咪喜欢吃鱼");
    }

    public void run() {
        System.out.println("猫咪在快乐的奔跑");
    }

    public static void drink() {
        System.out.println("小猫咪想喝水");
    }
}

当一个子类对象向上转型父类类型以后,就被当成了父类的对象,只能调用父类派生的方法(如set()、get()方法)以及子类重写了的父类的方法,而不能调用子类独有的方法
Java——向上转型和动态绑定机制
此时可以调用子类重写父类的eat()方法,单调用子类独有的方法run()就无效了
父类中的静态方法是不允许被子类重写的
父类Animal和子类Cat中都有静态方法drink(),测试类中调用时:

public class Test {
    public static void main(String[] args) {
        Animal cat = new Cat();     // 向上转型
        cat.drink();
    }
}

运行结果为:
Java——向上转型和动态绑定机制
它实际上调用的是父类的静态方法drink()

动态绑定

向上转型实现了将子类对象向上转型为父类类型,而动态绑定机制能识别出对象转型前的类型,从而自动调用该类的方法,两者相辅相成可以实现多态
静态绑定
静态绑定:在程序运行之前进行绑定(由编译器和链接程序完成的),也叫做前期绑定
如Animal派生出子类Cat、Dog、Pig,三个子类都重写了父类的eat()方法,在测试类中:

Cat cat = new Cat();
cat.eat();
Dog dog = new Dog();
dog.eat();
Pig pig = new Pig();
pig.eat();

这种方式,代码编译时编译器就知道cat调用的是Cat里的eat()方法
动态绑定
在测试代码中做一下改动:

Animal[] animal = new Animal[5]    // 生成父类对象数组
for (int i = 0; i < animal.length; i++) {
	int n = (int)(Math.random() * 3);
	switch (n) {
		case 0 : animal[i] = new Cat(); break;
		case 1 : animal[i] = new Dog(); break;
		case 2 : animal[i] = new Pig(); break;
	}
}
for (int i = 0; i < animal.length; i++) {
	animal[i].eat();
}

此时,Animal类中随机生成Cat类、Dog类、Pig类的对象,编译器不能根据代码直接确定调用哪个类中的eat()方法,直到运行时才能根据产生的随机数n来确定animal[i]到底代表哪一个子类的对象,这样才能最终确定调用的是哪个类中的eat()方法,这就是动态绑定