多态(Polymorphism)
多态是指不同的实例执行同一个命令时表现出的不同行为或现象,这个特性可以解决代码复用性过高的问题。
举个简单的例子,就如投喂宠物,当投喂的宠物是猫时,便投喂猫粮,当投喂的宠物是狗时,便投喂狗粮。根据投喂对象的不同,投喂的食物种类也不同,这就是多态。
多态的实现条件
两个对象(类)存在继承关系,子类对父类中的方法进行重写。此时在实例化子类对象时调用方法时,则会调用对应子类中重写的方法。
Java中,实现这个特性的原因是
-
一个对象的编译类型和运行类型可以不一致
-
编译类型在定义对象时就确定,不能改变
-
运行类型是可以变化的
-
一个对象的编译类型是父类,则可以指向(接收)的对象可以是子类的对象
Animal animal = new Dog();
//animal编译类型是Animal, 运行类型Dog
animal = new Cat();
//animal的运行类型变成了Cat, 编译类型仍然是Animal
注意事项
- 属性无多态性,当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性
- 构造方法无多态性
向上转型
本质:父类引用指向子类的对象
语法:
Animal animal = new Dog();
//父类类型 引用名 = new 子类类型();
注意事项
- 通过向上转型可以解决部分代码复用问题,但无法调用子类中特有的方法
- 属性没有重写的说法,属性的值取决编译类型
向下转型
本质:使用子类引用指向父类引用指向的子类的对象
语法:
Animal animal = new Dog();
Dog dog = (Dog)animal;//向下转型
//子类类型 引用名 = (子类类型) 父类引用;
向下转型后即可调用子类特有的方法
注意事项
- 只能强制转换父类的引用,而不能转换父类的对象
- 强制转换时要保证转换父类的引用为当前目标类型的对象
//为了避免转型时类型不同的问题,可以利用instanceof关键字
if(animal instanceof Dog){//确定animal对象的类型为Dog,再执行转型
Dog dog = (Dog)animal;
}
动态绑定机制
1.当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
//演示代码
public class Test {
public static void main(String[] args) {
Animal animal1 = new Dog("汪汪");
Animal animal2 = new Cat("喵喵");
animal1.eat();
animal2.eat();
}
}
class Animal{
String name;
public Animal(String name) {
this.name = name;
}
void eat(){}
}
class Dog extends Animal{
public Dog(String name) {
super(name);
}
@Override
void eat(){
System.out.println(name + "吃狗粮");
}
}
class Cat extends Animal{
public Cat(String name) {
super(name);
}
@Override
void eat() {
System.out.println(name + "吃猫粮");
}
}
//运行结果
汪汪吃狗粮
喵喵吃猫粮
2.当调用对象属性时,没有动态绑定机制,哪里声明就哪里使用
多态的优缺点
优点:
-
降低代码的复用性,减少if-else的大量使用
-
提高了代码的可拓展性
缺点:
- 代码运行效率降低
本文的主要目的是充当学习笔记,同时强化学习效果,且兼有分享所学知识之意,欢迎批评指正。