多态
- 向上类型转换(三种)
是一种类型转换,类和类之间的转换(父类和子类)。
//1.直接传值:一个子类的对象 用 一个父类的引用去表示。
Animal animal = new Bird("圆圆");
animal.eat("小米");
//下面这种写法也可以,但平常都按照上面这样来写
Bird bird = new Bird("圆圆");
Animal animal = bird;
bird.eat("谷子");
animal.eat("小米");
//2.方法传参 : 将子类的对象作为实参传给函数,用父类的对象去接受,实现了向上类型转换
public static void main(String[] args){
Bird bird1 = new Bird("圆圆");
feed(bird1);
}
public static void feed(Animal animal) {
animal.eat("谷子");
}
//3.方法的返回值:将创建的子类对象 通过函数返回值 返回给父类对象接收
public static void main(String[] args){
Animal animal = findMyAnimal();
}
public static Animal findMyAnimal() {
Bird bird = new Bird("圆圆");
return bird;
}
- 动态绑定
发生在子类和父类有(名字相同,返回值相同,参数相同,功能不同)的方法 时,代码如何运行?
new 了谁,就运行谁的方法。
动态绑定过程的底层存储:
3. 方法重写 / 覆写
动态绑定时,子类和父类有 名字相同,返回值相同,参数相同,功能不同 的方法,而这两个方法就构成了重写(override)。重写方法的要求:
- 方法名相同
- 参数必须完全相同(个数和类型都相同)
- 返回值没啥要求,一般情况下让返回值也一样
- 子类的方法访问权限控制不应该比父类的小(一般设定成一样的)
- 普通方法可以重写,静态方法不能重写
重载(overload):方法名相同,参数不同,返回值类型不影响
方法的重写 和 重载 没有关系,两个不同的概念,只是有一些地方有点相同。
- 理解多态:
是一种思想方法,多态落实到代码上具体的体现形式就是这三个(向上转型、动态绑定、重写)
是封装的更进步一步,
对于类的调用者来说,多态就是"一个引用, 能表现出多种不同形态"
而对于类的实现者来说,是在子类和父类具有覆盖方法的前提下,父类引用子类对象(向上转型),并且父类引用去调用这个覆盖方法时,就形成了动态绑定。
Java中的多态:
父类 引用 子类对象 , 并且父类和子类有同名的覆盖方法,这个时候如果通过父类引用调用这个同名方法,就会发生动态绑定。
- 向下转型
和向上转相反,向下转型是子类应用父类对象,但相对于向上引用不太常见,用的比较少。
Animal animal = new Bird("圆圆");
animal.eat("谷子");
// 执行结果 圆圆正在吃谷子
animal.fly();
// 编译出错 找不到 fly 方法
//因为 动态绑定是发生在重写的基础上的,而fly() 函数并没有进行重写
那么想实现刚才的效果, 就需要向下转型
// (Bird) 表示强制类型转换
Bird bird = (Bird)animal;
bird.fly();
// 执行结果 圆圆正在飞
Animal animal = new Cat("小猫");
Bird bird = (Bird)animal;
bird.fly();
// 执行结果, 抛出异常 Exception in thread "main" java.lang.ClassCastException:
// Cat cannot be cast to Bird at Test.main(Test.java:35)
// 类型转换异常 animal是猫的实例,不是鸟的实例,猫的类里面没有fly()方法
instanceof 可以判定一个引用是否是某个类的实例. 如果是, 则返回 true. 这时再进行向下转型就比较安全了.
Animal animal = new Cat("小猫");
if (animal instanceof Bird) {
Bird bird = (Bird)animal;
bird.fly();
}
- super关键字 this关键字
理解:this是我,super是我爸,哪个对象要用我在的这个类,我就是哪个对象。