Java 面向对象编程——多态

向上转型

父类引用子类对象叫向上转型。

class Animal{

    public String name;
    public Animal(String name){
        this.name = name;
    }
    public void eat(){
        System.out.println(this.name + "正在吃");
    }
}
class Bird extends Animal{
    public Bird(String name) {
        super(name);
    }
    public void fly(){
        System.out.println(this.name + "正在飞");
    }
}
public class TestMain {
    public static void main(String[] args) {
        //父类引用子类对象 —— 向上转型
        Animal animal = new Bird("麻雀");
    }

当我们在Animal 的 eat 方法中添加一个标记后,再运行此方法↓

可以看到我们调用的就是 Animal 的 eat 方法

而当我们想调用 fly 方法的时候却报错了

可以得出:通过父类引用只能引用父类自己的方法或者属性。

向上转型发生条件:

1、直接赋值

Animal animal = new Bird("麻雀");
animal.eat();

2、传参

public class TestMain {
    
    public static void func1(Animal animal){
        animal.eat();        
    }

    public static void main(String[] args) {
        Bird bird = new Bird("小鸟");
        func1(bird);
    }

运行结果为:

3、返回值

public Animal func2(){
        Bird bird = new Bird("鸟儿");
        return bird;
    }

重写 Override

1、方法名相同

2、参数列表相同(参数的个数、类型)

3、返回值相同(返回值可以不同,但是需要遵循协变类型 → 返回值之间可以构成继承关系(了解))

4、继承关系上

下图两个箭头表示这两个方法构成重写方法

注意:

1、该方法的访问修饰限定符不能是 private

2、访问修饰限定符不一定是相同的,只要满足:子类的访问修饰限定符大于等于父类的访问修饰限定符

3、静态的方法不能被重写

运行时绑定(动态绑定):多态

1、向上转型:父类引用子类对象

2、子类和父类有相同的覆盖方法

3、通过父类的引用,调用该方法,此时就会发生动态绑定

实例化 Animal 对象的时候调用它的子类对象 Cat:

这里调用的是 Cat 下面的eat()

我们运用 javap -c 类名 这个命令来进行反编译查看一下编译过程

我们可以看到编译的时候调用的是 Animal 的 eat(),但是运行的时候调用的是 Cat 的 eat()

这就是运行时绑定或动态绑定

经验分享 程序员 微信小程序 职场和发展