Java 三大特性(三)多态:instanceof与类型转换
一.多态定义
多态定义
- 多种形态
- 一个对象可以当做自己类的对象来看,也可以当做它的父类的对象来看
(对于这个对象来说,是多种形态)
- 一个父类引用可以指向它的不同子类的对象
(对于父类引用,也表现出多种形态)
多态的语法
//学生 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();
}