多态概述

同一个对象,在不同时刻表现出来的不同形态

举例:猫
我们可以说猫是猫:猫 cat = new 猫();
我们也可以说猫是动物:动物 animal = new 猫();
这里猫在不同的时刻表现出来了不同的形态,这就是多态

多态的前提和体现

  • 有继承/实现关系
  • 有方法重写
  • 有父类引用指向子类对象

多态中成员的访问特点

  • 成员变量:编译看左边,执行看左边
  • 成员方法:编译看左边,执行看右边

为什么成员变量和成员方法的访问不一样呢?

  • 因为成员方法有重写,而成员变量没有
范例
1
2
3
4
5
6
7
8
9
10
11
12

package unit_13duotai.test1;

public class Animal {

public int age = 40;

public void eat(){
System.out.println("动物吃东西");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

package unit_13duotai.test1;

public class Cat extends Animal{

public int age = 20;
public int weight = 10;

@Override
public void eat() {
System.out.println("猫吃鱼");
}

public void playGame(){
System.out.println("猫捉迷藏");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

package unit_13duotai.test1;
/*测试类*/
public class AnimalDemo {
public static void main(String[] args) {
//有父类引用指向子类对象
Animal a = new Cat();

System.out.println(a.age);
// System.out.println(a.weight);


a.eat();
// a.playGame();
}
}

多态的好处和弊端

  • 多态的好处:提高了程序的拓展性

    • 具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
  • 多态的弊端:不能使用子类的特有功能

范例
1
2
3
4
5
6
7
8
9
10

package unit_13duotai.test2;

public class Animal {

public void eat(){
System.out.println("动物吃东西");
}
}

1
2
3
4
5
6
7
8
9
10
11

package unit_13duotai.test2;

public class Cat extends Animal{

@Override
public void eat() {
System.out.println("猫吃鱼");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14

package unit_13duotai.test2;

public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃屎");
}

public void lookDoor(){
System.out.println("狗看门");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

package unit_13duotai.test2;
/*动物操作类*/
public class AnimalOperator {
/*
public void useAnimal(Cat c){ //Cat c = new Cat();
c.eat();
}

public void useAnimal(Dog d){//Dog d = new Dog();
d.eat();
}
*/
public void useAnimal(Animal a){
//Animal a = new Cat();
//Animal a = new Dog();

a.eat();
// a.lookDoor();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

package unit_13duotai.test2;
/*测试类*/
public class AnimalDemo {
public static void main(String[] args) {
//创建动物操作类的对象,调用方法
AnimalOperator ao = new AnimalOperator();
Cat c = new Cat();
ao.useAnimal(c);

Dog d = new Dog();
ao.useAnimal(d);

Pig p = new Pig();
ao.useAnimal(p);
}
}

多态中的转型

  • 向上转型

    • 从子到父
    • 父类引用指向子类对象
  • 向下转型

    • 从父到子
    • 父类引用转为子类对象
范例
1
2
3
4
5
6
7
8
9
10

package unit_13duotai.test3;

public class Animal {

public void eat(){
System.out.println("动物吃东西");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

package unit_13duotai.test3;

public class Cat extends Animal{

@Override
public void eat() {
System.out.println("猫吃鱼");
}

public void playGame(){
System.out.println("猫捉迷藏");
}
}

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

package unit_13duotai.test3;
/*
向上转型
从子到父
父类引用指向子类对象
向下转型
从父到子
-父类引用转为子类对象
*/
public class AnimalDemo {
public static void main(String[] args) {
//多态
Animal a = new Cat(); //向上转型
a.eat();
// a.playGame();

/*
//创建Cat类对象
Cat c = new Cat();
c.eat();
c.playGame();
*/

//向下转型
Cat c = (Cat)a;
c.eat();
c.playGame();

}
}

多态转型内存图解

案例:猫和狗

需求:请采用多态的思想实现猫和狗的案例,并在测试类中进行测试

思路:

  1. 定义动物类(Animal)

    1. 成员变量:姓名,年龄
    2. 构造方法:无参,带参
    3. 成员方法:get/set方法,吃饭()
  2. 定义猫类(Cat),继承动物类

    1. 构造方法:无参,带参
    2. 成员方法:重写吃饭()
  3. 定义狗类(Dog),继承动物类

    1. 构造方法:无参,带参
    2. 成员方法:重写吃饭()
  4. 定义测试类(AnimalDemo),写代码测试