一、多态
- 多态故名思义,多种状态。比如Animal 这个类中,eat 方法是 公共的方法,但是当 People,Dog , Cat,继承时,我们知道人要吃的是米饭,狗要吃的是狗粮,猫要吃的是猫粮。所以当不同类型的引用(不同的对象)调用同一方法时,虽然是同一方法,但是产生的效果却是不一样的,这就叫多态
1.1、多态的概念
- 当不同的引用(不同的对象)调用同一方法时,产生不同的结果
1.2、多态的实现条件(缺一不可)
- 需要在继承的前提下
- 子类需要对父类的方法进行重写
- 需要父类的引用调用重写方法
1.3、多态的好处
- 比如说以前的手机来电,他只能显示电话号码。现在的手机不仅可以显示电话号码,还显示名字,地址。这样的改变,如果我有多态,就不需要对以前的代码进行修改,我只需要重新创建一个类,继承以前的那个类,重写一下来电显示那个方法就行
- 这样使得代码的可扩展性更强了
二、重写
- 在重写代码的前一行,加上@Override,可以让编译器帮我们效验我们重写得对不对
- 重写和重载都是多态的表现
2.1、什么是重写?
- 重写是对父类的方法,在子类中重新写
- 在子类中的方法,访问权限要大于等于父类的,类型要完全相同,方法名要完全一样,参数列表也要完全一样
2.2、重写的规则
- 子类中的重写方法的访问权限要大于等于父类中的
- 父类中需要重写的方法不能用 static, private ,final修饰,否则不能重写,构造方法也不能重写
- 子类中的重写方法的返回值类型可以和父类的不一样,但是这个返回值类型必须和父类构成继承关系,这个叫协变类型
2.3、重写和重载的区别
- 访问权限:重写:要求必须大于或等于父类的访问权限,重载:要求要相同
- 返回值类型:重写:要求要完全一致,重载:不要求
- 方法名:重写:要求完全一致,重载:也是要求完全一致
- 参数列表:重写:要求完全一致,重载:参数列表必须不同(类型,名字,顺序)
2.4、动态绑定
- 比如说我用 Animal 类,实例化一个Dog 对象(向上转型),我们知道,animal这个引用虽然指的是Dog,但是animal 的类型是Animal,所以animal这个引用只能调用Animal中的成员,不能调用Dog中特有的成员。换句话说,父类的引用只能调用父类中的成员,不能调用子类的成员。更深层的意思就是,发生了向上转型不能调用制类特色的成员
- 什么是动态绑定?动态绑定也叫做运行时绑定。当我用animal调用重写的方法时,本应该调用的是父类中的方法,但是实际是调用了子类中的重写方法。这就是动态绑定
class Animal {public void eat()){sout("父类"+"正在吃饭...")}
}
class Dog extends Animal{
@Overridepublic void eat(){ sout("子类"+"正在吃饭...")}
}
class Tect{Animal animal = new Dog(); 因为此时发生了动态绑定animal.eat;
}
- 同一个引用调用同一个方法,当这个引用 ,引用的对象不一样的时候,调用方法产生的结果也不一样,此时我们就把这种思想称之为多态
2.5、静态绑定
- 什么是静态绑定?静态绑定也叫做(就是在写代码时绑定)编译时绑定。例子就是重载,跟据所传入的参数来调用合适的方法,此时就发生了静态绑定。(因为方法名字一样,所以根据你传入的参数来绑定要调用的方法,这就叫编译时绑定)
三、向上转型和向下转型
3.1、什么是向上转型,什么是向下转型?
Animal animal = new Dog();
Dog dog = (Dog)new Animal();
3.1.2、在向上转型中两个类型不一样,为什么不需要强制类型转换?
- 可以这么说,狗一定是动物,但动物不一定是狗,所以向下转型需要强转
3.2、使用场景
Animal animal = new Dog();
public static void get(Animal animal){ animal.draw();
}
Dog dog = new Dog();
get(dog);
public Animal get(){ return new Dog();
}
3.3、需要注意什么?
- 向上转型和向下转型,其实都是为了类型的统一
- 向下转型需要注意,因为动物不一定是狗。所以可以使用 instanceof 关键字来让编译器效验是不是强转的类型,即用该关键字验证animal 所指的对象是不是狗,这样使用instanceof 保证了向下转型的安全性
Animal animal = new Dog();
if(animal instanceof Dog){Dog dog1 = (Dog) animal;
}else if(animal instanceof Cat){Cat cat = (Cat) animal;
}
四、避免在构造方法中调用重写方法