Java面向对象—多态
面向对象简称 OO(Object Oriented),20 世纪 80 年代以后,有了面向对象分析(OOA)、 面向对象设计(OOD)、面向对象程序设计(OOP)等新的系统开发方式模型的研究。对 Java 语言来说,一切皆是对象。把现实世界中的对象抽象地体现在编程世界中,一个对象代表了某个具体的操作。一个个对象最终组成了完整的程序设计,这些对象可以是独立存在的,也可以是从别的对象继承过来的。对象之间通过相互作用传递信息,实现程序开发。
面向对象的三大核心特性:
- 封装性
- 继承性
- 多态性
今天我们重点来讲解Java面向对象的第三个特性:多态性。
一、多态的定义
在Java里,多态是同一个行为具有不同表现形式或形态的能力,即对象多种表现形式的体现,就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
举个栗子:打印机分很多种,有黑白打印机和彩色打印机,黑白打印机打印的效果只能是黑白两色。彩色打印机打印效果可以是多种色彩的组合。同样是打印机,不同的型号打印出的结果不同。在我们开发过程中,同一父类,不同子类呈现的结果不同,就是多态。
二、多态的实现条件
- 实现继承关系:实现继承关系,是将两个类建立起必要的联系,通过这种联系,展现不同的引用形态。
- 重写父类方法:重新父类方法,是根据不同子类的不同情况,通过方法重写实现展示效果的不同,效果不同,就展示了类的不同形态。
- 父类的引用指向子类的对象:通过对父类引用的实例化,实例化出不同的子类对象,最终实现类的多种形态的展示。
示例代码:
飞机类
/**
* 飞机类
*
*/
public class Airplane {
public int wing;//飞机机翼数量
public String engine;//发动机型号
/**
* 飞机用途方法
*/
public void purpose() {
System.out.println("我是一架飞机,我能起飞");
}
}
轰炸机,继承飞机类
/**
* 轰炸机
*
*/
public class Bomber extends Airplane{
public int ammunition;//导弹数量
/**
* 轰炸机用途方法
*/
public void purpose() {
System.out.println("我是一架轰炸机,我能发射导弹");
}
}
民用客机,继承飞机类
/**
* 民用客机
*
*/
public class Aircraft extends Airplane{
public int guest;//载客人数
/**
* 民用客机用途方法
*/
public void purpose() {
System.out.println("我是一架民用客机,我能承载普通客人");
}
}
测试类
public class Test {
public static void main(String[] args) {
Aircraft aircraft=new Aircraft();//实例化民用客机类对象
Bomber bomber=new Bomber();//实例化轰炸机类对象
Airplane airplane=null;//创建飞机类引用
airplane=aircraft;//将民用客机对象赋值给飞机类引用
airplane.purpose();//调用飞机用途方法
airplane=bomber;//将轰炸机对象赋值给飞机类引用
airplane.purpose();//调用飞机用途方法
}
}
三、多态的好处
使用多态,我们可以很好的完成代码的解耦合工作,加强代码的可扩展性,使代码更加灵活,在不改变原有方法的情况下使类的可用性提高,灵活性增强。
- 降低模块的耦合度
- 增强可以类的可替换性
- 增强模块的可扩展性
- 增强模块的灵活性
四、对象转型
向上转型
父类的引用指向子类的对象,称为向上转型。 作用是:提高程序的扩展性。
public class Test {
public static void main(String[] args) {
Aircraft aircraft=new Aircraft();//实例化民用客机类对象
Bomber bomber=new Bomber();//实例化轰炸机类对象
Airplane airplane=null;//创建飞机类引用
airplane=aircraft;//将民用客机对象赋值给飞机类引用(向上转型)
airplane.purpose();//调用飞机用途方法
airplane=bomber;//将轰炸机对象赋值给飞机类引用(向上转型)
airplane.purpose();//调用飞机用途方法
}
}
向下转型
将子类的引用指向了父类的对象,该写法是对象的向下转型;向下转型不是自动的,需要强制类型转换符进行转换。作用:实现子类扩展方法的调用。
public class Test {
public static void main(String[] args) {
Aircraft boeing747=new Aircraft();//实例化子类对象
Airplane plane=boeing747;//将子类对象赋值给父类引用(向上转型)
Aircraft boeing_747=(Aircraft)plane;//将父类对象赋值给子类引用(向下转型)
boeing_747.purpose();//调用子类方法
}
}
instanceof关键字
instanceof是Java中的一个二元运算符,用来测试一个对象是否为一个类的实例。
public class Test {
public static void main(String[] args) {
Airplane airplane=new Bomber();
System.out.println(airplane instanceof Airplane);
System.out.println(airplane instanceof Bomber);
System.out.println(airplane instanceof Aircraft);
}
}
五、编译期多态与运行期多态
编译和运行的划分
编译期是指 代码编译成字节码的过程(不是写代码的过程)
运行期是指 类字节码被加载进内存(从静态结构转换为内存运行结构)的过程
编译期多态是指方法重载,运行期多态是指方法重写和向上(下)转型
那么为什么说方法重载是编译期多态呢?
因为调用哪个方法在编译成字节码的时候,是可以根据参数类型、参数个数就确定下来的。所以在编译过程中就确定了多态的结果。
又为什么说方法重写、向上转型是运行时多态呢?
因为在转型中或方法的调用涉及到了方法重写,此时需要先去父类中找到该方法,然后再去判断子类是否重写了该方法,如果子类重写了该方法,那么就会调用子类的方法。所以需要在代码运行时才能确定多态的结果。
六、面向对象的三大特性总结
面向对象的三大特性,为封装、继承、多态。个人认为,继承是三大特性的核心。封装是将代码进行整合,封装后增加代码的聚合度;继承是建立了类与类之间的关系,建立了耦合度;多态是通过重写方式实现不同效果的展示,降低了耦合度。三大特性是一个整体,虽然可以独立使用,但是相互配合,整合起来的代码,更有优势和效果,真正的去实现了代码的高内聚,低耦合。