类和对象进阶 - 多态

1. 理解多态

1.1 理解多态的前提

如果要理解多态,首先需要理解以下知识点

1. 理解什么是继承关系

2. 理解什么是向上转型

3. 理解什么是重写

4. 理解什么是动态绑定

什么是继承关系在上一章中已说明 在此不多叙述

什么是向上转型

父类引用 引用子类对象,也就是父类引用变量存储子类对象在堆上的地址

观察下面这个例子

class Animal {
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃");
    }
}
class Dog extends Animal {
    public String  color;

    public Dog(String name,int age, String color) {
        super(name,age);
        this.color = color;
    }
    public void barks() {
        System.out.println(this.name + "正在狗叫");
    }

}
public class TestDemo {
    public static void main(String[] args) {
        Dog dog = new Dog("小白",2,"白色");
        Animal animal = dog;
        
    }
}

什么是重写

什么是重写 ?

重写 就是在子类中重写父类中的成员方法 

那么 为什么需要重写 ? 重写有什么作用 ? 

在说明这些问题前 先确定一个点 向上转型的引用只能调用自己父类的成员 不能调用子类的 

什么意思呢?观察下面这幅图

回到之前的问题  为什么需要重写 ? 重写有什么作用 ? 

​​​​​​当子类重写父类方法后,向上转型的引用执行子类的方法 如图

这是为什么? 之前的例子确定的结论是 向上转型的引用只能调用自己父类的成员 不能调用子类的

这是因为 动态绑定

什么是动态绑定

什么是动态绑定 ?

程序在编译时认为调用的是父类的方法,但是在实际执行时绑定执行子类方法

发生动态绑定的前提是 子类和父类拥有相同的成员方法 (重写)

这也是为什么需要重写 ---》因为重写可以发生动态绑定 解决向上转型的引用只能调用自己父类的成员问题

1.2 什么是多态

直接看代码来 理解多态

class Animal {
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃");
    }
}
class Dog extends Animal {
    public String  color;

    public Dog(String name,int age, String color) {
        super(name,age);
        this.color = color;
    }
    public void barks() {
        System.out.println(this.name + "正在狗叫");
    }
    public void eat() {
        System.out.println(this.name + " 正在吃狗粮");
    }
}
class Bird extends Animal {
    public Bird(String name, int age) {
        super(name, age);
    }

    public void eat() {
        System.out.println(this.name + " 正在吃鸟粮");
    }
}
public class TestDemo {
    public static void func(Animal animal) {
        animal.eat();
    }
    public static void main(String[] args) {
        Animal dog = new Dog("小白",2,"白色");
        func(dog);

        Animal bird = new Bird("布谷鸟",1);
        func(bird);
    }
}

前面理解多态的前提 继承关系 向上转型 重写 动态绑定  都可以理解为 发生多态的条件

2. 重写注意点

1. 子类在重写父类的方法时,必须与父类方法原型一致: 返回值类型  方法名   (参数列表)  要完全一致

2. final static 关键字修饰的父类方法 子类不能重写

3. 重写的子类方法访问权限 一定  >= 父类方法访问权限

        判断规则(public > protected > default)

4. private 关键字修饰的父类方法 子类不能重写

5. 父类构造方法不能被写

6. 重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验

7. 被重写的方法返回值类型可以不同,但是必须是具有父子关系的 

3. 向下转型

什么是向下转型 ? 向下转型有什么作用 ?

先来回顾向上转型,向上转型是父类引用引用子类对象  向上转型是发生多态的条件之一

此时 由于向上转型 子类对象的引用类型为父类 所以只能调用父类的成员方法 无法调用子类

如何让 在不重写的情况下 让父类引用调用子类成员方法 ?  

使用向下转型 将父类引用强制转换为子类类型

class Animal {
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃");
    }
}
class Dog extends Animal {
    public String  color;

    public Dog(String name,int age, String color) {
        super(name,age);
        this.color = color;
    }
    public void barks() {
        System.out.println(this.name + "正在狗叫");
    }
    public void eat() {
        System.out.println(this.name + " 正在吃狗粮");
    }
}
class Bird extends Animal {
    public Bird(String name, int age) {
        super(name, age);
    }

    public void eat() {
        System.out.println(this.name + " 正在吃鸟粮");
    }
}
public class TestDemo {
    public static void func(Animal animal) {
        animal.eat();
    }
    public static void main(String[] args) {
        Animal animal = new Dog("小白",2,"白色");
        Dog dog = (Dog)animal;
        dog.barks();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值