当我开始寻找多态性的好处时,我在这里找到了this的问题。但在这里我无法找到答案。让我告诉我想找到什么。我在这里有一些课程:
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类中创建了两个对象,并且是Refrigerator
的引用。我完全理解,在rf
对象中,我可以调用trip()
的{{1}}方法,但该方法将隐藏在Refrigerator
对象中。现在我的问题是为什么我应该使用多态或为什么我应该使用
cm
当我没事的时候
CoolingMachines cm = new Refrigerator();
多态对象的效率是好还是重量轻?这两个对象的基本目的和区别是什么? Refrigerator rf = new Refrigerator();
和cm.start();
之间有什么区别吗?
答案 0 :(得分:71)
处理列表时很有用... 一个简短的例子:
List<CoolingMachines> coolingMachines = ... // a list of CoolingMachines
for (CoolingMachine current : coolingMachines) {
current.start();
}
或者当您想允许方法使用CoolingMachines
答案 1 :(得分:58)
如果您对了解具体课程感到满意,那就没有任何好处。但是,在许多情况下,您希望能够编写只知道基类或接口的代码。
例如,查看Iterables
中的Guava - 这是很多方法(大多数情况下)不关心正在使用Iterable
的实现。您是否真的希望每个实现都单独使用所有代码?
如果可以编码到抽象基类或接口,您可以在以后使用共享相同公共API但可能具有不同实现的其他实现。即使您只需要一个生产实现,您也可能需要其他实现进行测试。 (这在多大程度上取决于所讨论的课程。)
答案 2 :(得分:28)
以后如果您想使用AirConditioner
代替Refrigerator
进行冷却,那么只需要更改的代码为CoolingMachines cm = new AirConditioner();
答案 3 :(得分:17)
您要使用
的原因CoolingMachines cm = new Refrigerator();
以后您可以轻松使用其他CoolingMachines
。您只需要更改那一行代码,其余代码仍然可以使用(因为它只使用CoolingMachines
的方法,这种方法比特定的机器更通用,例如Refrigerator
)。
因此,对于Refrigerator
的特定实例,调用cm.start();
和rf.start()
的工作方式相同,但cm
也可能是不同的CoolingMachines
对象。该对象可以有start()
的不同实现。
答案 4 :(得分:7)
使用多态来进行方法重写和方法重载。其他类方法在不同的类中使用,然后有两个选项:第一个方法继承,第二个方法重写。这里扩展接口:使用它们,或者实现方法:逻辑写入它们。多态用于方法,类继承。
cm.start();
和rf.start();
之间有什么区别吗?
是的,两者都是彼此完全不同的对象。不要创建接口对象,因为Java不支持接口对象。为接口创建第一个对象,为Refrigerator类创建第二个对象。第二个目标。
答案 5 :(得分:5)
对问题的一般部分(我为什么要使用多态?)的最一般的答案是多态性实现了一些关键的面向对象设计原则,例如:
代码重用: 通过将所有“冷却机器”共有的代码放入冷却机中,您只需编写一次该代码,并且对该代码的任何编辑都会立即流下。
抽象: 人类的大脑只能跟踪这么多东西,但他们擅长类别和层次结构。这有助于了解大型项目中发生的事情。
封装: 每个类都隐藏了它正在做的事情的细节,并且只是基于基类的接口。
关注点分离: 很多面向对象的编程都是关于分配职责的。谁将负责这一点?专门的问题可以在子类中进行。
因此,多态性只是更大的oo图片的一部分,并且使用它的原因有时只有在你尝试“真正”编程时才有意义。
答案 6 :(得分:3)
多态的一个简单用例是你可以有一个coolingMachines数组,其中元素0是refrigator,元素1是AirConditioner等......
您无需执行任何检查或确定您正在处理的对象,以便致电旅行或启动等。
当从用户那里获取输入并且必须迭代所有对象并调用类似函数时,这可能是一个很大的好处
答案 7 :(得分:2)
以多态方式使用对象也有助于创建相关类的工厂或系列,这是实现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和这些新子类的对象也可以使用现有代码。
答案 8 :(得分:2)
我将给出一个易于理解的例子。让我们说你有一些json
{"a":[1,2],"sz":"text", "v":3, "f":1.2}
现在让我们以编程方式说出要列出的名称,类型和值。而不是为每种类型(a的数组,sz的字符串等)提供switch(),你可以只有一个基类型并调用一个完成其工作的函数。它比使用十几种类型的交换机更有效。
然后有接口原因的插件,lib和外部代码。