JAVA三大特性—多态

1、介绍

  • 多态是同一个行为具有多个不同表现形式或形态的能力
  • 多态就是同一个接口,使用不同的实例而执行不同操作
  • 多态性是对象多种表现形式的体现。

2、多态存在的必要条件

  • 继承
  • 子类重写父类方法
  • 父类引用指向子类对象

比如:

1
Parent parent = new Child();   // 使用父类类型的引用指向子类的对象

3、代码示例

①、基于继承实现的多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class Animal {

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 Animal {

/**
* 重写父类的eat()方法
*
* @param animal
*/
@Override
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 Animal {

public String name = "dog";

/**
* 重写父类的sleep()方法
*/
@Override
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); //字段不具有多态性,仍然是父类的属性值
}
}

测试结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 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修饰的静态方法是不能被子类覆盖的,可以利用这一特性达到隐藏的效果

  • 使用父类类型的引用指向子类的对象

  • 当子类和父类存在相同的字段时候,无论修饰符是什么,都会在各自的内存空间中存储数据,则字段不具有多态性

  • 如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法

  • 1
    2
    //  final修饰的对象不能改变其值;只能指向animal这个地址(引用关系不能变)但是对象里面的值可以改变。
    final Animal animal = new Cat();

②、基于接口实现的多态(不在举例,读者可以自行实现)

在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。