多态性的好处
当我开始寻找多态的好处时,我在这里find了这个问题。 但在这里我无法find我的答案。 让我告诉我想find什么。 在这里我有一些类:
class CoolingMachines{ public void startMachine(){ //No implementationion } public void stopMachine(){ //No implementationion } } class Refrigerator extends CoolingMachines{ public void startMachine(){ System.out.println("Refrigerator Starts"); } public void stopMachine(){ System.out.println("Refrigerator Stop"); } public void trip(){ System.out.println("Refrigerator Trip"); } } class AirConditioner extends CoolingMachines{ public void startMachine(){ System.out.println("AC Starts"); } public void stopMachine(){ System.out.println("AC Stop"); } } public class PolymorphismDemo { CoolingMachines cm = new Refrigerator(); Refrigerator rf = new Refrigerator(); }
现在,我在Demo类中创build了两个对象,并且是Refrigerator
引用。 我已经完全明白,从rf
对象,我可以调用Refrigerator
的trip()
方法,但该方法将隐藏cm
对象。 现在我的问题是为什么我应该使用多态或为什么我应该使用
CoolingMachines cm = new Refrigerator();
当我很好的时候
Refrigerator rf = new Refrigerator();
多态对象的效率是好还是轻? 这两个对象的基本目的和区别是什么? cm.start();
是否有区别cm.start();
和rf.start()
?
当你处理列表时它是有用的…一个简短的例子:
List<CoolingMachines> coolingMachines = ... // a list of CoolingMachines for (CoolingMachine current : coolingMachines) { current.start(); }
或者当你想允许一个方法与任何一个CoolingMachines
子类一起工作
如果你真的了解具体的课程,没有任何好处。 但是,在许多情况下,您希望能够编写仅知道基类或接口的代码。
例如,看看Guava中的Iterables
– 这是很多(大部分)不关心使用Iterable
实现的Iterable
。 你真的想要所有的代码分别为每个实施?
在可以编写抽象基类或接口的地方,您可以稍后使用共享相同公共API的其他实现,但可能有不同的实现。 即使您只需要一个生产实施,您也可能需要替代实施进行testing。 (这在很大程度上取决于所讨论的课程。)
因为以后如果你想使用AirConditioner
而不是Refrigerator
冷却,那么你只需要更改的代码是CoolingMachines cm = new AirConditioner();
你想使用的原因
CoolingMachines cm = new Refrigerator();
是你以后可以轻松使用不同的CoolingMachines
。 你只需要改变那一行代码,其余的代码仍然可以工作(因为它只使用CoolingMachines
方法,比一个特定的机器,比如Refrigerator
更通用)。
因此,对于Refrigerator
的特定实例,调用cm.start();
和rf.start()
以相同的方式工作,但cm
也可能是一个不同的CoolingMachines
对象。 而这个对象可以有不同的start()
。
第一个答案:
使用多态性进行方法重写和方法重载。 在不同的类中使用的其他类方法有两个选项:第一个方法被inheritance,第二个方法被覆盖。 这里扩展接口:使用它们,或者实现方法:逻辑写入它们。 多态用于方法,类的inheritance。
第二个答案:
cm.start();
是否有区别cm.start();
和rf.start();
?
是的,两者都是完全不同的对象。 不要创build接口对象,因为Java不支持接口对象。 第一个为界面创build的对象,第二个为冰箱类创build。 第二个对象现在。
对于你的问题的一般部分(为什么我应该使用多态性?)最普遍的答案是多态性实现了一些关键的面向对象的devise原则,例如:
-
代码重用:通过将所有“制冷机”共用的代码放入制冷机中,您只需编写一次该代码,即刻编辑该代码。
-
抽象:人类的大脑只能跟踪这么多东西,但他们擅长于分类和层次结构。 这有助于了解大程序中发生的事情。
-
封装:每个类隐藏它所做的细节,只是build立在基类的接口上。
-
关注点分离:很多面向对象的编程都是关于分配职责的。 谁来负责呢? 专门的问题可以在子类中进行。
所以多态性只是更大的oo图片的一部分,使用它的原因有时只有在你尝试做'真正的'oo编程时才有意义。
一个简单的多态使用情况是,你可以有一个冷却机器的数组,其中元素0是一个制冷器,元素1是AirConditioner等。
您不需要执行任何检查或确定要处理的对象以便呼叫出发或启动等。
当从用户处获得input并且必须迭代所有对象并调用类似的函数时,这可能是一个很大的好处
我会给一个容易理解的例子。 可以说你有一些JSON
{"a":[1,2],"sz":"text", "v":3, "f":1.2}
现在让我们以编程的方式说出你想要列出的名称,types和值。 而不是每个types(一个数组,string为sz,等)有一个switch(),你可以只有一个基types和调用一个函数,它的工作。 与使用十几种types的交换机相比,它的CPU效率更高。
然后有插件,库和外部代码与接口的原因。
多态使用对象也有助于创build工厂或相关类的家族,这是Factory Design Pattern如何实现的重要组成部分。 这是多态工厂的一个非常基本的例子:
public CoolingMachine CreateCoolingMachines(string machineType) { if(machineType == "ref") return new Refrigerator(); //other else ifs to return other types of CoolingMachine family }
使用上面的代码调用:
CoolingMachine cm = CreateCoolingMachine("AC"); //the cm variable will have a reference to Airconditioner class which is returned by CreateCoolingMachines() method polymorphically
另外,假设你有一个如下的方法使用具体的类参数Refrigerator
:
public void UseObject(Refrigerator refObject) { //Implementation to use Refrigerator object only }
现在,如果更改UseObject()
方法的上述实现以使用最通用的基类参数,调用代码将有利于通过多态传递任何参数,然后在方法UseObject()
:
public void UseObject(CoolingMachine coolingMachineObject) { //Implementation to use Generic object and all derived objects }
上面的代码现在更具可扩展性,因为其他子类可以稍后添加到CoolingMachines系列中,这些新子类的对象也可以使用现有的代码。