多态
概念:同一个对象,在不同时刻表现不同形态。比如你是学生,你也是一个男孩,有不同的形态。
Person student = new Student();
前提:
【1】有继承/实现
【2】有方法重写
【3 】有父类引用指向子类对象
父类:
package duotai;
public class Person {
int age = 0;
public void study() {
System.out.println("人需要学习");
}
}
子类1:【1】有继承/实现,【2】有方法重写
package duotai;
public class Student extends Person {//1.学生继承了人
int age =20;//年龄
int height =180 ;
public void study(){//方法重写
System.out.println("学生要学习");
}
public void paly(){
System.out.println("学生在玩");
}
}
测试类:【3 】有父类引用指向子类对象
package duotai;
public class test1 {
public static void main(String[] args){
//父类引用指向子类对象
Person student =new Student();
//成员变量看父类的
System.out.println(student.age);//输出结构是父类的age
//System.out.println(student.height);报错了,因为父类Person没有这个变量
//成员方法看子类的
student.study();//结果是学生重写的方法
//student.play();报错了,因为父类Person没有这个方法,
//不能访问子类特有的成员。
}
}
结果:
子类2:【1】有继承/实现,【2】有方法重写
package duotai;
public class Worker extends Person {
public void study(){
System.out.println("工人也要学习");
}
}
操作类:
package duotai;
public class PersonOperation {
//(Student s)代表传入Student类的对象
public void usePerson(Student s){//Student s =new Student()
s.study();
};
//Worker w代表传入Worker类的对象
public void usePerson(Worker w){//Worker w =new Worker()
w.study();
};
}
操作类(多态实现)
次方法用多态实现,函数usePerson的形参为Person类的类对象,而student和worker都继承了Person的类,对于不同类传入,编译器就Person p = new Studnet(),Person p = new Worker(),根据多态知识函数看子类的,这个Person P 就会调用属于各自子类的方法。
package duotai;
public class PersonOperation {
public void usePerson(Person p){
//Person p = new Studnet()
//Person p = new Worker()
p.study();
}
}
测试类2:
package duotai;
public class test1 {
public static void main(String[] args){
//父类引用指向子类对象
Person student =new Student();
//成员变量看父类的
System.out.println(student.age);//输出结构是父类的age
//System.out.println(student.height);报错了,因为父类Person没有这个变量
//成员方法看子类的
student.study();//结果是学生重写的方法
//student.play();报错了,因为父类Person没有这个方法
PersonOperation P =new PersonOperation();
Student s =new Student();
Worker w = new Worker();
//对象p调用了usePerson()函数,s传参给这个函数,
// s是学生类的对象,所有调用学生类的方法
P.usePerson(s);
P.usePerson(w);
}
}
多态要注意 的细节:
1. 多态情况下,子父类存在同名的成员变量时,访问的是父类的成员变量。
2. 多态情况下,子父类存在同名的非静态的成员函数时,访问的是子类的成员函数。(成员方法有重写)
3. 多态情况下,子父类存在同名的静态(static)的成员函数时,访问的是父类的成员函数。
4. 多态情况下,不能访问子类特有的成员。(缺点)
优点:
根据操作类2分析可得:多态提高了程序的扩展性,写一个操作类包含父类的形参,测试类就可以生成基本父类的不同对象,只有在测试生成对象即可,不要动操作类代码的。
多态转型
【1】向上转型:从子到父;
Person p =new Student();
p.study();
p.play();//报错,不能访问特有方法
【2】向下转型:从父到子;
Person p =new Student();
p.study();
p.play();//报错,不能访问特有方法
//向下转型 子类 子类对象名 = (子类)父类对象名
Student s =(Student)p;
s.play();通过向下转型,就行正常调用了
注意:不能向上转型一个子类,然后向下转型用另一个子类
多态形式
【1】:具体类多态:本节内容
【2】抽象类多态:https://blog.csdn.net/gun_wqy/article/details/123583028
【3】接口类多态:https://blog.csdn.net/gun_wqy/article/details/123589004