一.多态定义
多态定义
- 多种形态
- 一个对象可以当做自己类的对象来看,也可以当做它的父类的对象来看
(对于这个对象来说,是多种形态)
- 一个父类引用可以指向它的不同子类的对象
(对于父类引用,也表现出多种形态)
多态的语法
//学生 s = new 学生();
//人 p = new 学生();
//学生 is a 人
Person p = new Student();//多态语法
p = new Teacher();//多态语法
p.eat();
1.继承父类
2.重写父类方法(可以不用)
3.父类的引用指向子类的对象,子类对象赋值给父类的引用。
二.多态法则
(1)法则一
可以访问什么!
---------------------
若子类对象当父类对象看待, 只能访问父类中定义的成员属性与方法,而不能访
问子类的成员(扩展的部分)
(2)法则二
访问的到底是什么
--------------------
若子类对父类的方法进行覆盖(重写),则在调用时会调用子类对象重写的方法
(3)多态的机制是由什么决定
1 静态绑定
发生在编译期间,一个方法或一个属性能不能调用或访问,是看左边的类型来决定,父类的引用指向子类的对象
2 动态绑定
发生在运行时,会找到具体的那个对象的方法来执行
三.多态使用
(1)返回类型使用多态
public static Fruit getFruit(int type){ if(type==1){ return new Apple(); }else if(type==2){ return new Banana(); }else{ return null; } } Fruit tmp = new Banana();
(2)参数使用多态
class Person{ public void feed(Animal a,String food){ a.eat(food); } }class Animal{ public void eat(String food){ System.out.println("吃"+food); } }class Dog extends Animal{ public void eat(String food){ System.out.println("狗吃"+food); } }
(3)成员变量使用多态
p.setDog(new XXXDog());class Person{ private Dog dog ;//实例变量上使用多态,spring大量使用这种方式的多态 public void setDog(Dog dog){ this.dog = dog; } public void hunt(){ System.out.println("开枪射中猎物"); dog.runAndPick(); } }class Dog{ public void runAndPick(){ System.out.println("跑过去捡起猎物"); } }class GuiBinDog extends Dog{ public void runAndPick(){ System.out.println("跑过去看了看,被吓跑了"); } }class WolfDog extends Dog{ public void runAndPick(){ System.out.println("跑过去直接开吃。。。"); } }
(4)数组中使用多态
四.多态的好处
1 使得程序更加灵活和可扩展
2 提高可维护性
经常修改的问题
1 源代码找不到
2 修改bug容易引入更多的bug
基于上面问题提出一个软件设计原则
OCP - Open - Close - Principle - 开闭原则
对扩展开放,对修改关闭
(1)对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。
(2)对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。
五.instanceof与类型转换
java.lang.ClassCastException - 类型转换错误 instance - 实例instanceof - 判断当前实例是否是某种类型 Person p = new Student(); p.eat(); /* Teacher t = (Teacher)p; t.teach(); */ if(p instanceof Teacher){ Teacher t = (Teacher)p; t.teach(); }