多态性的好处

当我开始寻找多态的好处时,我在这里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对象,我可以调用Refrigeratortrip()方法,但该方法将隐藏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系列中,这些新子类的对象也可以使用现有的代码。