多态
概念:允许不同的类对象对同一事物做出不同的响应
- 多态的必要条件:
- 必须有继承(继承类和实现接口)
- 必须有重写
- 父类型的引用指向子类型的空间
- 多态的作用:提供代码的重用性。
- 引用的多态
- 父类的引用可以指向本类的对象
- 父类的引用可以指向子类的对象
- 方法的多态
- 引用数据类型之间的转换只能存在于父子类之间。引用数据类型转换,只能A空间转A类对象。
- 兄弟类中间不能通过父类中转转换
- 引用类型转换
- 向上转型(隐式/自动类型转换),是小类型到大类型的转换
- 子类型的引用自动转换为父类型引用
- 父类的引用可以保存子类的空间
- 向下类型转换(强制类型转换),是大类型到小类型
- 父类型的引用强制转换为子类型引用
- 父类转子类时,因为子类可以扩展出父类没有的属性和方法,所以可能发生错误,所以需要强制转换
- instanceof运算符,来解决引用对象的类型,避免类型转换的安全性问题。
- 检测引用所指向的对象的类型
public abstract class Person {
protected String name;
protected String sex;
public Person(String name, String sex) {
this.name = name;
this.sex = sex;
}
public void eat(){
System.out.println("干饭人,干饭魂,干饭就是人上人");
}
}
public class Teacher extends Person {
public Teacher(String name, String sex) {
super(name, sex);
}
public void work() {
System.out.println("桃李满天下");
}
}
public class Student extends Person{
public Student(String name, String sex) {
super(name, sex);
}
public void readBook(){
System.out.println("书中自有黄金屋,书中自有颜如玉------白日梦");
}
}
public class Test {
Person stu=new Student("li4","男");
Person tea=new Teacher("wan5","男");//向上转型
//当Person去掉abstract,也就是Person不在是抽象类时,
//就可以new一个Person了
//Person p=new Person("zhan3","男");
stu.eat();
System.out.println(tea.name);
Student student=(Student) stu;//向下转型
//这时把Person强转为Student时,编译不会报错,
//但当它运行时却会报类型不能转换的错误。
//Student stu1=(Student) p;
//stu1.readBook();
student.readBook();
}
}
总结:
类型转换只能发生在父类与子类之间,类型转换只能是A空间转换为A类型。
A空间转换为A类型:
“Person stu=new Student(“li4”,“男”);”这一句语句其实可以分为两句,“Person stu=null; 1
stu=new Student(); 2”
语句1是声明一个Person的变量stu,是告诉虚拟机stu是一个什么类型的变量,它有什么属性和方法:语句2是为变量stu的赋值,这里stu保存的是堆中开辟出的一个Student空间的地址。首先stu是一个Person变量,所以虽然它保存的是一个Student值,但它还是只能调用Person里面有的属性和方法,对于Student里面扩展出来的属性和方法它无法调用,虽然这些方法和属性都存在。
“Student student=(Student) stu;”这里stu
的类型是Person,虽然它保存的是Student类型的值,为了把Person类型的stu值传给student,只能把stu转为Student型
这里也就需要强转。
Person是Student的父类,Person有的Student都有,但Student有的,Person不一定有,所以Student转Person不会出现任何问题(向上转型),但Person转为Student却会出现一些属性或方法的缺失,所以Java不支持但也不否定,于是也就需要我们人为的转换,也就是强转(向下转型)。
多态的使用
public interface OnAndOff{
void on();
void off();
}
public class Light implements OnAndOff{
@Override
public void on() {
System.out.println("开灯");
}
@Override
public void off() {
System.out.println("关灯");
}
}
public class Fan implements OnAndOff{
@Override
public void on() {
System.out.println("开风扇");
}
@Override
public void off() {
System.out.println("关风扇");
}
}
public class Switch {
private boolean isTurn=false;
public void onAndOff(OnAndOff onAndOff){
System.out.println("关");
String str="";
Scanner in=new Scanner(System.in);
while (!str.equals("end")){
str=in.nextLine();
isTurn=!isTurn;
if (isTurn){
onAndOff.on();
}else {
onAndOff.off();
}
}
}
}
public class SwitchTest {
public static void main(String[] args) {
Light light=new Light();
Fan fan=new Fan();
Switch s=new Switch();
s.onAndOff(fan);
//light和fan都实现了OnAndOff接口,
//在实例化switch并调用onAndOff时,实现了向上转型,
}
}