Java 多态
多态
- 即同一方法可以根据发送对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)
public class Person {
public void run(){
System.out.println("run");
}
public void eat(){
System.out.println("eat!");
}
}
public class Student extends Person{
@Override
public void run() {
System.out.println("Don't run!");
}
}
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型就不确定了:父类的引用类型指向子类
//Person类 父类,可以指向子类,但是不能调用子类独有的方法
Person person = new Student();
//Student 子类,能调用的方法都是自己的或者是继承父类的!
Student student = new Student();
person.run();//方法引用地址指向子类,父类这个方法被重写了,所以执行重写方法,若没被重写,由于子类继承了父类的方法,所以就执行子类继承父类的方法
student.run();
// 对象能执行哪些方法主要看对象左边引用类型,和右边的关系不大
person.eat();
}
- 多态存在的条件:
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
个人见解:
个人认为, Father father = new Son() 中,在堆中,本来 father 的方法引用地址是指向父类的,也就是说应该是根据 Father 这个父类方法模板来复制方法给 father 这个对象。但我们人为将 father 的方法引用地址指向了 Son 这个类,即 father 这个对象将根据 Son 这个模板来复制方法(与属性无关,是哪个类就指向哪个类),也就是说此时 father 为 Son 这个类的实例。前提是这两个类是有关联的,而且只能复制子类重写的父类方法,子类独有的方法并不能复制。
注意:多态是方法的多态,属性没有多态!!!
instanceof
- 测试左边的对象是否是右边类的实例,返回Boolean值。
- 当对象是右边类或子类所创建的对象时,返回true;否则,返回false。
- 左边声明的变量类型和右边的操作元必须是在同一个继承树下,否则会编译报错!
public static void main(String[] args) {
//Object > Person > Student
//Object > Person > Teacher
Person person = new Person();
System.out.println(person instanceof Student);//false person为Person类的实例,也就是对象,而Person类为Student类的父类
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true Person类为Object类的子类,符合条件
System.out.println(person instanceof Teacher);//false Person类为Teacher类的父类,不符合条件
System.out.println("========================");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher); //编译报错 两个类不再同一个继承树下,毫无关系
System.out.println("========================");
Object object = new Student();
System.out.println(object instanceof Student);//true Object的引用指向了Student类,则此时object为Student的实例
System.out.println(object instanceof Person);//true object为Student的实例,也就是对象,Student为Person的子类,符合对象是右边类的对象或者子类的对象
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
System.out.println("========================");
Person person1 = new Student();
System.out.println(person1 instanceof Student);//true Person的引用指向了Student类,此时person为Student类的实例
System.out.println(person1 instanceof Person);//true
System.out.println(person1 instanceof Object);//true
System.out.println(person1 instanceof Teacher);//false
}
类型转换
- 子类转换为父类,向上转型:父类的引用指向子类!
- 父类转换为子类,向下转型:强制转换
- 将父类转换为子类,这样父类就可以调用子类独有的方法,减少重复的代码!
public static void main(String[] args) {
//类型之间的转换: 父 子
//父类(高)----> 子类(低)
Person person = new Person();
((Student)person).go();
}