多态简单来说就是:一个对象对应着不同的类型(例如有一个动物类,一个猫类,猫类继承了动物类,那么猫这个对象属于猫类也属于动物类)
在代码中体现为:父类或者接口的引用指向其子类的对象。
多态的好处:提高了代码的扩展性,前期定义的代码可以使用后期的内容。
多态的弊端:前期定义的内容不能使用(调用)后期子类的特有内容。
多态的前提:
1,必须有关系,继承,实现。
2,要有覆盖。
那么什么是提高代码的扩展性,前期定义代码可以使用后期的内容呢?
还是拿动物和猫类来举例子。
class Animal{
public void eat(){
//动物吃东西的行为
System.out.println("吃东西");
}
}
class Cat extends Animal{
//有自己独有的吃东西方法覆盖父类
public void eat(){
System.out.println("爱吃鱼");
}
}
现在有一个方法要接受一个动物对象然后执行该动物的吃东西方法,目前只有猫一个具体动物我们可以这样写。
animalEat(Cat cat){
cat.eat()
}
那如果我们确定具体动物不肯能只有猫一个,但是现在也不知道会有什么具体动物怎么办?难道没增加一个具体动物类我们就要重新写个类似的方法?当然不是啦,这时候多态就发挥作用了,也即就是前期定义代码可以使用后期的内容。
我们把上面的方法改一下
animalEat(Animal animal){
animal.eat();
}
调用的时候用父类(动物 Animal)引用指向子类(具体动物 Cat)对象
Animal cat=new Cat();//(类型向上提升)
animalEat(cat);
新增一个Dog类
class Dog extends Animal{
eat(){
System.out.println("吃骨头");
}
}
使用时只需要跟上面一样将Dog的实例做类型提升即可
Animal dog=new Dog();//将Dog实例提升为Animal类型
animEat(dog);
不需要为每一个动物子类定义animalEat方法。这就是多态的好处:前期定义代码可以使用后期的内容。
什么又是是前期定义的内容不能使用(调用)后期子类的特有内容呢?这是多态的一个弊端
我们修改Cat类添加一个成员变量
class Cat extends Animal{
public name="cat"
public void eat(){
System.out.println("爱吃鱼");
}
}
修改animalEat方法
animalEat(Animal animal){
System.out.println("name:"+animal.name);
animal.eat();
}
现在调用
Animal cat=new Cat();//(类型向上提升,向上转型,将子类型隐藏。就不用使用子类的特有方法。)
animalEat(cat);//编译时会失败。
这就是前期定义的内容不能使用(调用)后期子类的特有内容。
补充:如果对Cat类做了类型提升Animal cat=new Cat();还想访问Cat类的特有成员可以对cat对象向下转型Cat newCat=(Cat) cat;