1.多态的概念:同一个对象在不同时刻体现出来的不同状态。
2.多态的前提:
A:有继承或者实现关系。
B:有方法的重写。(如果没有重写,使用多态就没有意义)
C:有父类或父接口引用指向子类对象。
3.多态的分类
A:具体类多态
class Father{}
class Son extends Father{}
Father f=new Son();
B:抽象类多态
abstract class Father {}
class Son extends Father {}
Father f = new Son();
C:接口多态
interface Father {}
class Son implements Father {}
Father f = new Son();
4.多态中成员访问特点
A:成员变量
编译时看父类,运行看父类
B:构造方法
子类构造默认访问父类构造
C:成员方法
编译时看父类,运行时看子类
D:静态方法
编译时看父类,运行看父类
例:
class Father {
public int num = 100;
public void show() {
System.out.println("show Father");
}
public static void function() {
System.out.println("function Father");
}
}
class Son extends Father {
public int num = 1000;
public int num2 = 200;
public void show() {
System.out.println("show Son");
}
public void method() {
System.out.println("method Son");
}
public static void function() {
System.out.println("function Son");
}
}
class DuoTaiDemo {
public static void main(String[] args) {
//要有父类引用指向子类对象。
Father f = new Son();
//成员变量访问特点
System.out.println(f.num); //输出100,即运行看父类
//System.out.println(f.num2); //找不到符号,即编译看父类,父类没有该变量,所以报错
//成员方法访问特点
f.show(); //输出show Son,即运行看子类
//f.method(); //找不到符号,即编译看父类,父类没有该方法,所以报错
f.function(); //输出function Father,即编译看父类,有则通过,运行看父类,输出父类结果
}
}
5.多态的好处
A:提高代码的维护性(继承体现)
B:提高代码的扩展性(多态体现)
abstract class Animal {
public void shoot() {}
}
class Dog extends Animal {
public void shoot() {
System.out.println("汪汪");
}
}
class Cat extends Animal {
public void shoot() {
System.out.println("喵喵");
}
}
class Person{
private Animal animal;
public Person(){}
public Person(Animal animal){
this.animal=animal;
}
public void shoot(){
animal.shoot();
}
public void setAnimal(Animal animal){
//运用参数多态,以后方便养别的宠物
this.animal=animal;
}
}
public class Test {
public static void main(String[] args) {
//我喜欢猫,就养了一只
Person p=new Person();
Cat c = new Cat();
p.setAnimal(c); //先养了只猫
p.shoot();
//我又喜欢狗了,所以换狗养
Dog d = new Dog();
p.setAnimal(d);
p.shoot();
//我喜欢宠物狼,老虎,豹子...
//只需要定义对应的类,继承自Animal,提供对应的方法重写 ,不用特地去Person类中添加。
}
}
6.多态的弊端与转型
父类不能使用子类的特有功能。
如:上文第4点,成员方法访问特点。
那么,如何改进才能调用呢?就用多态的转型。
A:向上转型
B:向下转型
Father father = new Son();//向下转型
Son son = (Son)father;//向上转型
son.show();
son.method();
转型后,就可以在不多占用内存的情况下(创建子类对象)调用子类特有方法。
7.多态内存占用图解
A:多态继承内存占用图解
B:多态中对象变化内存占用
8.多态猫狗案例
/*
多态练习:猫狗案例
*/
class Animal {
public void eat(){
System.out.println("吃饭");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
public void lookDoor() {
System.out.println("狗看门");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
class DuoTaiTest {
public static void main(String[] args) {
//定义为狗
Animal a = new Dog();
a.eat();
System.out.println("--------------");
//还原成狗
Dog d = (Dog)a;
d.eat();
d.lookDoor();
System.out.println("--------------");
//变成猫
a = new Cat();
a.eat();
System.out.println("--------------");
//还原成猫
Cat c = (Cat)a;
c.eat();
c.playGame();
System.out.println("--------------");
//演示错误的内容
//Dog dd = new Animal();
//Dog ddd = new Cat();
//Dog dd = (Dog)a; //ClassCastException 类转换出错
}
}