学习总结:
链接:【Java基础、springboot、springcloud、docker 等,学习目录】
多态:
1、一个对象具备多种状态。
Animal a = new Dog();
Animal a = new Cat();
Animal a = new Dinosaur();
2、父类的引用类型变量指向了子类的对象,或者是接口的引用类型变量指向了接口的实现类对象。
3、多态即向上转型的过程:父类类型 变量名 = new 子类类型(); 子类对象赋值给一个父类引用。
4、向下转型:强制类型转换。一个已经向上转型的对象,使用强制类型转换将父类引用转为子类引用(如果是直接创建父类对象,是无法向下转型的),向下转型可以访问子类特有的成员。
// 直接创建父类对象
Person person = new Person();
Student student = (Student) person; // java.lang.ClassCastException
System.out.println(student.city);
// 向下转型
Person person = new Student();
Student student = (Student) person;
System.out.println(student.city);
一、多态前提:
1、必须存在继承关系或实现关系。
2、要有方法重写。使用多态后的父类引用类型变量调用方法时,会调用子类重写后的方法。
二、多态注意细节:
1、成员变量: 子父类存在同名的成员变量时,访问的是父类的成员变量。
2、非静态成员函数: 子父类存在同名的非静态的成员函数时,访问的是子类的成员函数(即,子类重写父类的方法),
4、静态成员函数: 子父类存在同名的静态成员函数,访问的是父类的成员函数(这种情况下不算重写,因为静态成员是和类相关的,静态跟对象没有关系)。
5、多态情况下,不能访问子类特有成员,需要强制类型转换后才可访问。
第5点的解释:编译看左边,运行不一定看右边:
编译、运行 | 解释 |
---|---|
编译看左边 | java编译器在编译的时候,会检查引用类型变量所属的类是否具备指定的成员,如果不具备马上报错。 |
运行不一定看左边 | 非静态看右边 |
Demo:
// 父类
public class Person {
// 子父类同名成员变量
String name = "person";
// 同名非静态成员方法
public void heart(){
System.out.println("The one : " + name);
}
// 同名静态成员方法
public static void game(){
System.out.println("父类静态方法");
}
}
// 子类
public class Student extends Person {
// 同名成员变量
String name = "student";
// 子类特有成员
String city = "ShenZheng";
// 同名非静态成员函数
@Override
public void heart(){
System.out.println("The one : " + name);
}
// 同名静态成员函数
public static void game(){
System.out.println("子类静态方法");
}
}
// 测试:
public static void main(String[] args) {
Person p = new Student();
System.out.println(p.name); // person
p.heart(); // The one : student
Person.game(); // 父类静态方法
System.out.println(((Student)p).city); // 访问子类特有成员需要强制类型转换
}
总结:
多态情况下,子父类存在同名的成员时,访问的都是父类的成员,除了在同名非静态函数时,访问的才是子类的成员函数。
三、多态的应用:
1、作为形式参数类型时,可以接受更多类型的参数(可以接收父类所有子类类型)。
2、用于返回值类型,可以返回更多类型的数据。
多态的优缺点:
优缺点 | 要点 |
---|---|
优点 | 隐藏了子类类型,提高代码的拓展性,向上转型 |
弊端 | 只能使用父类共性的内容,无法使用子类特有的功能, |
四、接口关系下的多态:
接口(相当于父类) 变量 = new 接口实现类对象(相当于子类)
三种多态的定义格式:
// 1、普通定义格式:
父类 变量名 = new 子类();
// 2、抽象类定义:
抽象类 变量名 = new 抽象类子类();
// 3、接口多态:
接口 变量 = new 接口实现类对象;