多态概述
- 同一个对象,在不同时刻表现出来的不同形态
举例:猫
我们可以说猫是猫:猫cat = new猫();
我们也可以说猫是动物:动物animal = new猫();
这里猫在不同的时刻表现出来了不同的形态,这就是多态
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
多态中成员访问特点
成员变量: 编译看左边,执行看左边
成员方法: 编译看左边,执行看右边
静态方法:编译和运行都看等号左边
为什么成员变量和成员方法的访问不- -样呢?
- 因为成员方法有重写, 而成员变量没有
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
class Animal {
public int age = 30;
public void eat(){ //被重写
System.out.println("动物吃东西");
}
public void show(){ //没被重写
System.out.println("show");
}
}
class Cat extends Animal{
public int age = 5;
public int weight = 34;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame(){
System.out.println("猫捉迷藏");
}
}
public class Demo {
public static void main(String[] args) {
//父类引用指向子类对象
Animal c1 = new Cat();
System.out.println(c1.age);
//System.out.println(c1.weight);//编译报错
c1.show(); //show
c1.eat();//猫吃鱼
//c1.playGame();//编译报错
}
}
多态的好处和弊端
- 多态的好处: 提高了程序的扩展性
具体体现:定方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作 - 多态的弊端: 不能使用子类的特有功能
class Animal {
public void eat(){
System.out.println("动物吃食物");
}
}
Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void lookDoor(){
System.out.println("狗看门");
}
}
class AnimalOperator {
//省去
/*public void useAnimal(Cat cat){
cat.eat();
}
public void useAnimal(Dog dog){
dog.eat();
}*/
//只需定义一个方法
public void useAnimal(Animal a){
a.eat();
//a.lookDoor();//编译报错 不能调用子类特有的方法
}
}
public class AnimalDemo {
public static void main(String[] args) {
AnimalOperator operator = new AnimalOperator();
Cat cat = new Cat();
operator.useAnimal(cat);//猫吃鱼
Dog dog = new Dog();
operator.useAnimal(dog);//狗吃骨头
}
}
多态中的转型
解决了多态的弊端
-
向上转型
从子到父
父类引用指向子类对象 -
向下转型
从父到子
父类引用转为子类对象
class Animal {
public void eat(){
System.out.println("动物吃食物");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame(){
System.out.println("小猫捉迷藏");
}
}
public class AnimalDemo {
public static void main(String[] args) {
Animal cat = new Cat(); //向上转型
cat.eat(); //猫吃鱼
//cat.playGame(); //编译报错
Cat c = (Cat) cat; //向下转型
c.eat(); //猫吃鱼
c.playGame(); //小猫捉迷藏
}
}