多态性的好处[关闭]

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 对象我可以调用Refrigeratortrip() 方法,但是对于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。 是的,这绝对只是一个例子。为了更深入地理解概念,最好设计一个可扩展、可读且可能遵循设计模式的应用程序(在设计类图时很有用)。 它也被设计为遵守里氏替换原则:该原则指出,如果ST 的子类型,那么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 不支持接口对象。为接口创建的第一个对象,为冰箱类创建的第二个对象。现在是第二个对象。

【讨论】:

让我向您介绍我最亲密的两个朋友ShiftEnter。欢迎来到我们的社区,但在这里我们喜欢格式化,而不是盲目地打字。另外,我需要您查看我所做的更改,并确保它们保持您帖子的意图。随意编辑。我认为您在陈述中犯了一些错误,但我并不完全确定。【参考方案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 这也是我想说的,工厂使用多态代码,但多态代码还有其他要求..

以上是关于多态性的好处[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

什么是多态性,使用多态有什么好处?

多态的好处??

JAVA之旅——多态的体现,前提,好处,应用,转型,instanceof,多态中成员变量的特点,多态的案例

java8-3 多态的好处和弊端以及多态的理解

多态在面向对象中的意义以及带来的好处

多态的好处作用