多态性的好处[关闭]
Posted
技术标签:
【中文标题】多态性的好处[关闭]【英文标题】:Benefit of Polymorphism [closed] 【发布时间】:2012-06-20 09:51:12 【问题描述】:当我开始寻找多态的好处时,我发现这里有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
对象我可以调用Refrigerator
的trip()
方法,但是对于cm
对象,该方法将被隐藏。现在我的问题是我为什么要使用多态或者我为什么要使用
CoolingMachines cm = new Refrigerator();
当我同意时
Refrigerator rf = new Refrigerator();
多态对象的效率好还是重量轻?这两个对象的基本目的和区别是什么? cm.start();
和rf.start()
有区别吗?
【问题讨论】:
【参考方案1】:在处理列表时很有用... 一个简短的例子:
List<CoolingMachines> coolingMachines = ... // a list of CoolingMachines
for (CoolingMachine current : coolingMachines)
current.start();
或者当你想让一个方法与CoolingMachines
的任何子类一起工作时
【讨论】:
这显然只是它如何有用的一个例子。基本上,你可以有通用的 API。 是的,这绝对只是一个例子。为了更深入地理解概念,最好设计一个可扩展、可读且可能遵循设计模式的应用程序(在设计类图时很有用)。 它也被设计为遵守里氏替换原则:该原则指出,如果S
是T
的子类型,那么T
可以替换每次出现的S
【参考方案2】:
如果您对了解具体类真的没问题,那就没有好处了。但是,在许多情况下,您希望能够编写只知道基类或接口的代码。
例如,查看Guava 中的Iterables
- 很多方法(大部分)并不关心正在使用Iterable
的哪个实现。您真的希望所有代码分别用于每个实现吗?
如果您可以编码到抽象基类或接口,则您允许自己稍后使用共享相同公共 API 但可能具有不同实现的其他实现。即使您只想要一个生产 实现,您也可能需要替代实现来进行测试。 (这在很大程度上取决于所讨论的类。)
【讨论】:
然后让我们开始使用依赖注入之类的东西。基于接口的编程有很多优点。 @jcolebrand,比如针对接口进行测试,而不是实现。那么你的单元测试并不关心数据是从数据库、平面文件还是稀薄的空气中提取的。集成测试应该,但那是另一回事;)【参考方案3】:因为以后如果你想用AirConditioner
而不是Refrigerator
来冷却,那么你只需要更改代码是CoolingMachines cm = new AirConditioner();
【讨论】:
【参考方案4】:你要使用的原因
CoolingMachines cm = new Refrigerator();
是您以后可以轻松使用不同的CoolingMachines
。您只需要更改那一行代码,其余代码仍然可以工作(因为它只会使用CoolingMachines
的方法,这比特定机器更通用,例如Refrigerator
)。
因此对于Refrigerator
的特定实例,调用cm.start();
和rf.start()
的工作方式相同,但cm
也可能是不同的CoolingMachines
对象。该对象可能有不同的start()
实现。
【讨论】:
【参考方案5】:第一个答案:
将多态性用于方法覆盖和方法重载。不同类中使用的其他类方法然后有两个选项:第一个方法继承,第二个方法覆盖。这里扩展接口:使用它们,或者实现方法:逻辑编写它们。用于方法、类继承的多态性。
第二个答案:
cm.start();
和 rf.start();
有什么区别吗?
是的,两者都是彼此完全不同的对象。不要创建接口对象,因为 Java 不支持接口对象。为接口创建的第一个对象,为冰箱类创建的第二个对象。现在是第二个对象。
【讨论】:
让我向您介绍我最亲密的两个朋友Shift
和Enter
。欢迎来到我们的社区,但在这里我们喜欢格式化,而不是盲目地打字。另外,我需要您查看我所做的更改,并确保它们保持您帖子的意图。随意编辑。我认为您在陈述中犯了一些错误,但我并不完全确定。【参考方案6】:
对于您的问题的一般部分(我为什么要使用多态?),最一般的答案是多态实现了一些关键的面向对象设计原则,例如:
代码重用: 通过将所有“冷却机”通用的任何代码放入冷却机中,您只需编写该代码一次,对该代码的任何编辑都会立即生效。
抽象: 人脑只能记录这么多东西,但他们擅长分类和层次结构。这有助于了解大型程序中正在发生的事情。
封装: 每个类都隐藏了它正在做的事情的细节,只是建立在基类的接口上。
关注点分离: 许多面向对象的编程都是关于分配职责的。谁来负责这件事?专门的关注点可以放在子类中。
因此,多态性只是 oo 大图的一部分,使用它的原因有时只有在您要尝试进行“真正的”oo 编程时才有意义。
【讨论】:
【参考方案7】:多态性的一个简单用例是您可以拥有一个coolingMachines 数组,其中元素0 是冰箱,元素1 是空调等...
您无需执行任何检查或确定您正在处理的对象即可调用 trip 或 start 等。
当从用户那里获取输入并且必须遍历所有对象并调用类似的函数时,这可能是一个很大的好处
【讨论】:
【参考方案8】:我将举一个容易理解的例子。假设你有一些 json
"a":[1,2],"sz":"text", "v":3, "f":1.2
现在让我们以编程方式说您想要列出名称、类型和值。而不是为每种类型(a 的数组,sz 的字符串等)都有一个 switch(),您可以只拥有一个基本类型并调用一个完成其工作的函数。它也比使用具有十几种类型的开关更高效。
然后是有接口原因的插件、库和外来代码。
【讨论】:
不错,更不用说switch语句添加更多类型等维护了!【参考方案9】:以多态方式使用对象还有助于创建相关类的工厂或系列,这是实现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 和这些新子类的对象也可以与现有代码一起使用。
【讨论】:
我认为您的部分解释倒退了。人们使用工厂作为允许多态代码的一种手段,而不是作为多态代码的终点。 我同意missingo的观点,工厂只是处理Java和C#等现代OOP语言所施加的限制的一种手段。 @missingno 这也是我想说的,工厂使用多态代码,但多态代码还有其他要求..以上是关于多态性的好处[关闭]的主要内容,如果未能解决你的问题,请参考以下文章