文章目录
多态
多态的概述
-
什么是多态?
答:同一个对象,在不同的时刻有多种形态
比如:
Animal an = new Cat(); Animal an = new Dog();
-
多态的举例
- 绿巨人 , 是正常人的时候是班纳,发怒后就变为绿巨人
- 毛毛虫,刚开始是个虫,过段时间后就变为蝶了。
-
多态的形式:具体类多态、抽象类多态、接口多态
-
多态的前提
-
要有实现 || 继承关系
-
要有方法的重写
体现:继承关系下,子类重写父类的方法;实现关系下,实现类 来实现接口中的方法
-
父类的引用类型的变量指向了子类对象,接口的引用类型变量指向了实现类对象
-
多态中成员访问特点
-
成员访问特点
-
成员变量(实际开发中不太关注)
编译看左边,运行看左边
-
成员方法(重点掌握)
编译看左边,运行看右边
总结:编译全看左边,只有成员方法运行看右边
代码展示:
// 动物类 public class Animal { public int age = 40; public void eat() { System.out.println("动物吃东西"); } } // 猫类 class Cat extends Animal { public int age = 10; public int weight = 10; public void eat() { System.out.println("猫吃鱼"); } public void playGame() { System.out.println("猫捉迷藏"); } } // 编写测试类 class AnimalTest { public static void main(String[] args) { // 父类的引用类型的变量指向了子类对象 Animal an = new Cat(); System.out.println(an.age); an.eat(); an.playGame(); } }
-
多态的好处和弊端
-
好处
提高了程序的扩展性
具体体现:定义方法时,使用父类 | 接口类型作为方法形参,在调用该方法时,将 不同的子类对象 | 不同的实现类对象作为方法实参传入。
-
弊端
继承关系下的多态,不能访问子类的特有成员,实现关系下的多态,不能访问实现类的特有成员,若要访问必须向下转型
写一个多态程序的步骤(必须掌握)
继承关系下的多态:
- 写一个父类
- 写一个或多个子类继承父类,重写父类中的方法
- 写一个父类的使用类(或者叫做操作类),在使用类中定义一个方法,方法的形式参数类型就是父类类型
- 写一个测试类,在main方法中,创建使用类对象,调用其方法,将不同的子类对象作为其方法的实际参数传入
实现关系下的多态:
- 写一个接口
- 写一个实现类,实现类实现该接口,并实现接口中的所有抽象方法
- 写一个接口的使用类,在使用类中定义一个方法,方法的参数类型就是接口类型
- 写一个测试类,在main方法中,创建使用类对象,调用其方法,其方法的参数要传入不同的实现类对象
多态中的转型
-
向上转型(就是多态的格式)
父类的引用类型变量指向了子类对象 ,比如:
Animal an = new Cat();
接口的引用类型变量指向了实现类对象,比如:
SpeakEnglish se = new PingPang();
-
向下转型(也叫做强制类型转换)
父类的引用类型变量强转为子类对象,格式: 子类型 对象名 = (子类型) 父类引用;,比如:
Animal an = new Cat(); // Cat是Animal的子类,Animal是Cat的父类 Cat cat = (Cat)an;
接口的引用类型变量强转为实现类对象,格式:实现类类型 对象名 = (实现类类型)接口引用;,比如:
SpeakEnglish se = new PingPang();// PingPang是SpeakEnglish接口的实现类 PingPang pp = (PingPang)se;
向下转型一定会成功吗?
需要使用
instanceof
运算符,来判断对象是否属于某种类型,属于返回true,否则返回false,比如:public void useAnimal(Animal an) { an.eat(); if(an instanceof Wolf) { Wolf wolf = (Wolf)an; wolf.howl(); } }
代码展示:
// 动物类
public class Animal {
public void eat() {
System.out.println("动物吃东西");
}
}
// 猫类
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
// 测试类
class AnimalTest {
public static void main(String[] args) {
Animal an = new Cat(); // 向上转型
an.eat(); // 编译看左边,运行看右边
Cat cat = (Cat)an; // 向下转型
cat.eat(); // 编译看左边,运行看右边
cat.platGame();
}
}
多态的案例
需求:用多态思想实现猫和狗的案例,并在测试类中进行测试
代码展示:
// 动物类
public class Animal {
// 编写属性
protected String name;
protected int age;
// 编写无参构造
public Animal() {
// super()
}
// 编写带参构造
public Animal(String name ,int age) {
this.name = name;
this.age = age;
}
// 编写成员方法
// setXxx()方法 和 getXxx() 方法
public void setName(String name) {
this.name = name ;
}
public String getName() {
return name;