这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战程序员
🎉上一篇学习了多态的基础语法,多态在实际开发中有什么做用呢?编程
咱们先来了解一个业务背景:请设计一个系统,描述主人喂养宠物的场景,首先在这个场景当中应该有“宠物对象”,宠物对象应该有一个吃的行为,另外还须要一个“主人对象”,主人对象应该有一个喂的行为,请看代码:markdown
//宠物狗
public class Dog {
String name;
public Dog(String name){
this.name = name;
}
//吃的行为
public void eat(){
System.out.println(this.name + "在啃肉骨头!");
}
}
复制代码
//主人
public class Master {
//喂养行为
public void feed(Dog dog){
//主人喂养宠物,宠物就吃
System.out.println("主人开始喂食儿");
dog.eat();
System.out.println("主人喂食儿完毕");
}
}
复制代码
public class Test {
public static void main(String[] args) {
//建立狗对象
Dog dog = new Dog("二哈");
//建立主人对象
Master master = new Master();
//喂养
master.feed(dog);
}
}
复制代码
运行结果以下图所示:app
以上程序编译和运行都很正常,输出结果也是对的,那么存在什么问题吗?ide
假设后期用户提出了新的需求,软件可能面临着功能扩展,这个扩展会很方便吗?oop
假设如今主人家里又来了一个宠物猫,那该怎么办呢?post
请看代码:学习
在以上代码的基础之上,新增了一个Cat类,来表示宠物猫,这个对于程序来讲是能够接受的:测试
//宠物猫
public class Cat {
String name;
public Cat(String name){
this.name = name;
}
//吃的行为
public void eat(){
System.out.println(this.name + "在吃鱼!");
}
}
复制代码
另外,除了增长一个Cat类以外,咱们还须要“修改”Master主人类的源代码,这件事儿是咱们程序员没法容忍的,由于修改以前写好的源代码就面临着从新编译、从新全方位的测试,这是一个巨大的工做,维护成本很高,也很麻烦:ui
//主人
public class Master {
//喂养行为
public void feed(Dog dog){
//主人喂养宠物,宠物就吃
System.out.println("主人开始喂食儿");
dog.eat();
System.out.println("主人喂食儿完毕");
}
//喂养行为
public void feed(Cat cat){
//主人喂养宠物,宠物就吃
System.out.println("主人开始喂食儿");
cat.eat();
System.out.println("主人喂食儿完毕");
}
}
复制代码
public class Test {
public static void main(String[] args) {
//建立狗对象
Dog dog = new Dog("二哈");
//建立主人对象
Master master = new Master();
//喂养
master.feed(dog);
//建立猫对象
Cat cat = new Cat("汤姆");
//喂养
master.feed(cat);
}
}
复制代码
运行结果以下图所示:
在软件开发过程当中,有这样的一个开发原则:开闭原则。开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它不少的设计原则都是实现开闭原则的一种手段。
1988年,勃兰特·梅耶(Bertrand Meyer)在他的著做《面向对象软件构造(Object Oriented Software Construction)》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”。
这句话说得略微有点专业,咱们把它讲得更通俗一点,也就是:软件系统中包含的各类组件,例如模块(Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能。
开闭原则中“开”,是指对于组件功能的扩展是开放的,是容许对其进行功能扩展的;
开闭原则中“闭”,是指对于原有代码的修改是封闭的,即修改原有的代码对外部的使用是透明的。
以上程序在扩展的过程中就违背了OCP原则,由于在扩展的过程中修改了已经写好的Master类,怎样能够解决这个问题呢?多态能够解决,请看代码:
//宠物类
public class Pet {
String name;
//吃的行为
public void eat(){
}
}
复制代码
//宠物猫
public class Cat extends Pet{
public Cat(String name){
this.name = name;
}
//吃的行为
public void eat(){
System.out.println(this.name + "在吃鱼!");
}
}
复制代码
//宠物狗
public class Dog extends Pet{
public Dog(String name){
this.name = name;
}
//吃的行为
public void eat(){
System.out.println(this.name + "在啃肉骨头!");
}
}
复制代码
//主人
public class Master {
//喂养行为
public void feed(Pet pet){
//主人喂养宠物,宠物就吃
System.out.println("主人开始喂食儿");
pet.eat();
System.out.println("主人喂食儿完毕");
}
}
复制代码
public class Test {
public static void main(String[] args) {
//建立狗对象
Dog dog = new Dog("二哈");
//建立主人对象
Master master = new Master();
//喂养
master.feed(dog);
//建立猫对象
Cat cat = new Cat("汤姆");
//喂养
master.feed(cat);
}
}
复制代码
运行结果以下图所示:
在以上程序中,Master类中的方法feed(Pet pet)的参数类型定义为更加抽象的Pet类型,而不是具体Dog宠物,或者Cat宠物,显然Master类和具体的Dog、Cat类解耦合了,依赖性弱了,这就是咱们一般所说的面向抽象编程,尽可能不要面向具体编程,面向抽象编程会让你的代码耦合度下降,扩展能力加强,从而符合OCP的开发原则。假如说这会再来一个新的宠物猪呢,咱们只须要这样作,新增长一个“宠物猪类”,而后宠物猪类Pig继承宠物类Pet,并重写eat()方法,而后修改一下测试类就好了,整个过程咱们是不须要修改Master类的,只是额外增长了一个新的类:
public class Pig extends Pet {
public Pig(String name){
this.name = name;
}
//吃的行为
public void eat(){
System.out.println(this.name + "在吃粥!");
}
}
复制代码
public class Test {
public static void main(String[] args) {
//建立狗对象
Dog dog = new Dog("二哈");
//建立主人对象
Master master = new Master();
//喂养
master.feed(dog);
//建立猫对象
Cat cat = new Cat("汤姆");
//喂养
master.feed(cat);
//建立宠物猪对象
Pig pig = new Pig("小猪猪");
master.feed(pig);
}
}
复制代码
运行结果以下图所示:
以上程序中到底哪里使用了多态机制呢?请看下图:
经过以上内容的学习,咱们能够看到多态在开发中联合方法覆盖一块儿使用,能够下降程序的耦合度,提升程序的扩展力。在开发中尽量面向抽象编程,不要面向具体编程,比如电脑主板和内存条的关系同样,主板和内存条件之间有一个抽象的符合某个规范的插槽,不一样品牌的内存条均可以插到主板上使用,2个G的内存条和4个G的内存条均可以插上,但最终的表现结果是不一样的,2个G的内存条处理速度慢一些,4个G的快一些,这就是多态,所谓多态就是同一个行为做用到不一样的对象上,最终的表现结果是不一样的,主要的要求就是对象是能够进行灵活切换的,灵活切换的前提就是解耦合,解耦合依赖多态机制。