一.多态性的理解:一个事物的多种形态。比如动物就具有多态性,动物有猫、狗、猪…等。
二.对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
例如:Animal animal = new Cat();
三.多态性的使用: 虚拟方法的调用
- 有了对象的多态性后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
- 总结:编译,看左边;运行,看右边(针对方法,属性的编译和运行都看左边)
四.多态性使用的注意点:
- .必须存在继承关系
- .适用于方法,不适用于属性
- 不能用父类的引用指向子类中没有在父类中重写的方法。
补充(2020.6.15):向上转型和向下转型和使用instanceof
一.向上转型:
Animal animal = new Cat();//Animal是父类,Cat是子类这就是向上转型,这就是多态的一种体现
二.向下转型:
Animal animal = new Cat();
Cat cat = (Cat)animal;//把父类型转为子类型,这就是向下转型
三.为什么要向上转型和向下转型?
1.向上转型就是多态的一种体现,为什么要用多态呢?我的理解是想让一个类具有多种形态。
2.为什么要向下转型呢?因为虽然使用多态了,但是父类的引用只能指向子类中那些重写过的方法,无法指向子类中的特定的方法,特定的方法是指子类中没有重写父类方法的那些方法,所以需要向下转型,这样就能指向子类中特定的方法了。用段代码来理解一下
public class Animal {//父类
public void eat(){//父类中的方法
System.out.println("动物吃饭");
}
}
class Cat extends Animal{//子类
public void eat(){//子类重写父类中的方法
System.out.println("猫吃饭");
}
public void climb(){//子类的特定方法
System.out.println("猫爬树");
}
}
class TestAnimal{//测试类
public static void main(String[] args) {
Animal animal = new Cat();//使用多态
animal.eat();//这里调用的eat方法是子类中的eat,因为eat重写了父类中的eat方法
animal.climb();//这里是编译报错的,因为这是子类特有的方法,并没有重新父类中的方法
Cat cat = (Cat)animal;//进行向下转型
cat.climb();//调用子类中特有的方法
}
}
四.instanceof的使用
a intanceof A:a代表一个对象,A代表一个类(注意a和A是不同的,一个是对象一个是类)
含义是:a是否属于A中的一个实例(猫是动物中的一个实例)如果属于返回true,反之false
//Animal是父类Cat是子类
Animal a = new Animal();//创建一个父类对象
Cat c = new Cat();//创建一个子类对象
Animal a1 = new Cat();//使用多态
System.out.println(c instanceof Animal);//true
System.out.println(Animal instanceof c);//false,
System.out.println(a1 instanceof Animal);//true
System.out.println(a1 instanceof Cat);//true
上面前两个大家可能都能理解,但是后两个是不是就奇怪了?为什么a1这个对象能属于两个类呢?它难道比别人多个爹么?其实这就是多态的多种形态的体现了,当a1被创建的时候他的堆空间中既包含了Animal的属性方法也包含了Cat的属性方法,这些东西确确实实在堆空间中,所以当使用instanceof时你会发现它两个都属于。(注意:我只说了a1的堆空间存在Animal和Cat的属性方法,并没有说a1能直接调用!!!我只是想让大家对instance的理解加深一点。)