1、介绍
- 多态是同一个行为具有多个不同表现形式或形态的能力
- 多态就是同一个接口,使用不同的实例而执行不同操作
- 多态性是对象多种表现形式的体现。
2、多态存在的必要条件
- 继承
- 子类重写父类方法
- 父类引用指向子类对象
比如:
Parent parent = new Child();
3、代码示例
①、基于继承实现的多态
public class {
public String name = "animal";
public void eat(Animal animal){
System.out.println("animal say ......");
}
public void sleep(){
System.out.println("animal sleep......");
}
public static void speak(){
System.out.println("animal speak .......");
}
}
public class Cat extends {
/**
* 重写父类的eat()方法
*
* @param animal
*/
public void eat(Animal animal) {
System.out.println("****************************************");
if (animal instanceof Animal) {
System.out.println("animal is instanceof Animal.....");
}
if (animal instanceof Cat) {
System.out.println("animal is instanceof Cat.....");
}
if (animal instanceof Dog) {
System.out.println("animal is instanceof Dog.....");
}
if (animal instanceof Object) {
System.out.println("animal is instanceof Object.....");
}
System.out.println(animal + " say .......");
System.out.println("****************************************");
}
}
public class Dog extends {
public String name = "dog";
/**
* 重写父类的sleep()方法
*/
public void sleep() {
System.out.println("dog sleep......");
}
public static void speak() {
System.out.println("dog speak .......");
}
}
//测试案例
public class TestMain {
public static void main(String[] args) {
Animal animal1 = new Cat();
//父类的引用,根据传入不同的子类实例,在运行期间会表现出具体子类的特征
animal1.eat(new Cat());
animal1.eat(new Dog());
Animal animal2 = new Dog();
animal2.sleep(); // 非静态方法,JVM调用的是具体子类的sleep(Dog)的方法
animal2.speak(); // 静态方法不能被重写,仍然调用的是父类的speak方法
System.out.println(animal2.name); //字段不具有多态性,仍然是父类的属性值
}
}
测试结果
// animal 对象体现的多态性,是 Animal,Dog,Object的实例
****************************************
animal is instanceof Animal.....
animal is instanceof Cat.....
animal is instanceof Object.....
com.gulj.springbootvalidator.duotai.Cat@378bf509 say .......
****************************************
****************************************
animal is instanceof Animal.....
animal is instanceof Dog.....
animal is instanceof Object.....
com.gulj.springbootvalidator.duotai.Dog@5fd0d5ae say .......
****************************************
dog sleep......
animal speak .......
总结说明
对象具有两种类型:
- 编译类型(编译类型必须是运行类型的父类或相同)
- 运行类型
在形式上,类定义的对象只能看到自己所属类中的成员。父类对象无法看到子类的新扩充方法。
父类被关键词static修饰的静态方法是不能被子类覆盖的,可以利用这一特性达到隐藏的效果
使用父类类型的引用指向子类的对象
当子类和父类存在相同的字段时候,无论修饰符是什么,都会在各自的内存空间中存储数据,则字段不具有多态性
如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法
// final修饰的对象不能改变其值;只能指向animal这个地址(引用关系不能变)但是对象里面的值可以改变。
final Animal animal = new Cat();
②、基于接口实现的多态(不在举例,读者可以自行实现)
在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。