第一点:
多态的确定:在程序中,多态就是用父类的引用指向子类 的对象 例如:Person p = new Student(); Person是父类,Student是子类
第二点:
工作的机制:1、先通过p保存的地址找到Student对象 2、再使用Student对象去工作,实际工作的是对象
第三点:继承和多态中调用成员变量和成员方法比较
情景:父类:Person 子类:Teacher和Student
多态的前提是继承,所以有以下继承
class Person{}
class Teacher extends Person{}
class Student extends Person{}
(1)表现形式:
继承:Teacher teacher = new Teacher();
多态:Person person = new Teacher();
相同点:对象都是子类(即new Teacher())
不同点:继承中的引用类型与对象的类型相同(此处是子类Teacher)
多态中的引用类型是对象类型的父类(此处是Teacher的父类Person的引用)
所以,在调用成员变量和成员方法中,通过子类类型调用就是继承,通过父类类型调用就是多态
(2)调用成员变量
继承:通过继承调用成员变量,调用顺序为子类--->父类--->父类的父类--->...--->基类,知道找到为止就不再向下寻找,此处形式为:teacher.成员变量
多态:通过多态调用成员变量,只会且只能调用父类里面的成员变量,不管是否会向下转型(向下转型的目的只是为了用父类的引用来调用子类特有的方法),如果父类中有该成员变量则对其赋值,否则,编译错误,此处形式为:person.成员变量
(3)调用成员方法(非静态成员方法)
继承:通过继承调用成员方法,调用顺序为子类--->父类--->父类的父类--->...--->基类,知道找到为止就不再向下寻找,此处形式为:teacher.成员方法
多态:
①通过多态调用成员方法,如果父类与子类有相同方法名的方法,则不需要向下转型即可调用子类的方法(因为最后工作的还是对象,即new Teacher(),如果父类有相同的方法名,则 person.成员方法 只是编译用,并没有运行,当运行的时候,就通过对象new Teacher()来调用成员方法)
②如果通过父类引用要调用子类中独有的方法时,就需要向下转型(强制将父类的引用类型转成子类的引用转型:Teacher teacher = (Teacher)person,然后用 teacher.成员方法 来调用子类特有的方法);
(4)调用静态方法
不管是父类中静态方法还是子类的静态方法,通过相应的类名调用即可,是可以实现继承的
注意:静态属性、静态方法和非静态的属性都可以被继承和隐藏而不能被重写,因此不能实现多态,不能实现父类的引用可以指向不同子类的对象。非静态方法可以被继承和重写,因此可以实现多态。
第四点:
如果一个方法中需要传入的是Cat的实参,但客户输入了Dog类型的实参,这时候就需要做容错处理,使用instanceof关键字(构成: 对象 instanceof 类 结果两个:true/false):
if(animal1 instanceof Cat){
//干猫的活
}
实际工作中写成下面这样:
if(!(animal1 instanceof Cat)){
}
//干猫的活
在多态的前提下,当确定传过来的对象确定是Cat的对象,再去干猫的活,否则直接跳过干下面的工作,这样做可以保证当前位置发生的问题不影响整个程序的运行,做一个预防的工作---容错处理.---增加用户的体验