什么是多态性,它的用途是什么,如何使用它?


当前回答

我为另一个问题提供了多态性的高级概述:

c++中的多态性

希望能有所帮助。一个提取…

...从简单的测试和[多态性]定义开始会有所帮助。考虑下面的代码:

Type1 x;
Type2 y;

f(x);
f(y);

这里,f()是执行一些操作,并被赋予值x和y作为输入。要具有多态性,f()必须能够操作至少两种不同类型的值(例如int和double),查找并执行适合类型的代码。

(继续在Polymorphism in c++)

其他回答

多态性字面上的意思是多种形状。(或多种形式): 对象来自不同的类和同名方法,但工作流不同。 一个简单的例子是:

假设一个人X。

他只是一个人,但他的行为却像许多人一样。 你可能会问:

他是他母亲的儿子。 朋友对朋友。 兄弟之于姐妹。

OOP中的多态性意味着一个类可以有不同的类型,继承是实现多态性的一种方式。

for example, Shape is an interface, it has Square, Circle, Diamond subtypes. now you have a Square object, you can upcasting Square to Shape automatically, because Square is a Shape. But when you try to downcasting Shape to Square, you must do explicit type casting, because you can't say Shape is Square, it could be Circle as well. so you need manually cast it with code like Square s = (Square)shape, what if the shape is Circle, you will get java.lang.ClassCastException, because Circle is not Square.

简单类比解释

美国的总统采用多态。怎么做?他有很多顾问:

军事顾问 法律顾问 核物理学家(作为顾问) 等等。

每个人只应该对一件事负责:

总统不是镀锌层专家,也不是量子物理专家。他不知道很多事情。但他知道如何管理国家。

代码也是一样:关注点和职责应该被分离到相关的类/人。这使得维护代码更加容易,特别是当您正在进行更改时。变化是不可避免的。当事情发生变化时,您不希望破坏应用程序的其他部分。总统们应该专注于管理国家,而不是进入专业领域的细节:

为什么一个总统知道所有这些具体的事情是一个坏主意?

如果总统明确地告诉人们要做什么,那就意味着总统需要确切地知道要做什么。如果总统自己需要知道具体的事情,这意味着当你需要做出改变时,你需要在两个地方做出改变,而不仅仅是一个地方。

例如,如果EPA改变了污染法律,那么当这种情况发生时:你必须对EPA类和总统类进行更改。在两个地方而不是一个地方更改代码可能是危险的——因为它更难维护。

有没有更好的方法?

有一个更好的方法:总统不需要知道任何事情的细节——他可以从专门负责这些事情的人那里得到最好的建议。

他可以用多态的方法来治理国家。

使用多态方法的例子:

总统所做的就是让人们给他提建议——这就是他在现实生活中所做的——这就是一个好总统应该做的。他的顾问们都有不同的反应,但他们都知道总统是什么意思:Advise()。成百上千的人涌进他的办公室。他们是谁并不重要。总统所知道的是,当他要求他们“建议”时,他们知道如何相应回应:

public class MisterPresident
{
    public void RunTheCountry()
    {
        // assume the Petraeus and Condi classes etc are instantiated.
        petraeus.Advise(); // # Petraeus says send 100,000 troops to Fallujah
        condolezza.Advise(); // # she says negotiate trade deal with Iran
        healthOfficials.Advise(); // # they say we need to spend $50 billion on ObamaCare
    }
}

这种方法允许总统在不了解任何军事、医疗或国际外交的情况下管理国家:细节留给专家。总统需要知道的唯一一件事是:“Advise()”。

你不想要的:

public class MisterPresident
{
    public void RunTheCountry()
    {
        // people walk into the Presidents office and he tells them what to do
        // depending on who they are.

        // Fallujah Advice - Mr Prez tells his military exactly what to do.
        petraeus.IncreaseTroopNumbers();
        petraeus.ImproveSecurity();
        petraeus.PayContractors();

        // Condi diplomacy advice - Prez tells Condi how to negotiate

        condi.StallNegotiations();
        condi.LowBallFigure();
        condi.FireDemocraticallyElectedIraqiLeaderBecauseIDontLikeHim();

        // Health care

        healthOfficial.IncreasePremiums();
        healthOfficial.AddPreexistingConditions();
    }
}

NO! NO! NO! In the above scenario, the president is doing all the work: he knows about increasing troop numbers and pre-existing conditions. This means that if middle eastern policies change, then the president would have to change his commands, as well as the Petraeus class as well. We should only have to change the Petraeus class, because the President shouldn't have to get bogged down in that sort of detail. He doesn't need to know about the details. All he needs to know is that if he makes one order, everything will be taken care of. All the details should be left to the experts.

这使得总统可以做他最擅长的事情:制定总体政策,保持良好的形象,打高尔夫球。

它实际上是如何实现的——通过基类还是公共接口

简而言之,这实际上就是多态性。具体是怎么做到的呢?通过“实现一个公共接口”或者通过使用基类(继承)——参见上面的回答,它们更详细地说明了这一点。(为了更清楚地理解这个概念,您需要知道接口是什么,还需要了解继承是什么。否则,你可能会很挣扎。)

换句话说,Petraeus、Condi和healthoofficial都是“实现接口”的类——让我们称其为IAdvisor接口,它只包含一个方法:Advise()。但现在我们进入细节。

这是最理想的

    public class MisterPresident
    {
            // You can pass in any advisor: Condi, HealthOfficials,
            //  Petraeus etc. The president has no idea who it will 
            // be. But he does know that he can ask them to "advise" 
            // and that's all Mr Prez cares for.

        public void RunTheCountry(IAdvisor governmentOfficer)
        {             
            governmentOfficer.Advise();              
        }
    }


    public class USA
    {
        MisterPresident president;

        public USA(MisterPresident president)
        {
            this.president = president;
        }

        public void ImplementPolicy()
        {
            IAdvisor governmentOfficer = getAdvisor(); // Returns an advisor: could be condi, or petraus etc.
            president.RunTheCountry(governmentOfficer);
        }
    }

总结

你真正需要知道的是:

总统不需要知道细节——那些是留给别人的。 总统所需要知道的是问谁曾经走进家门给他建议-我们知道他们绝对知道当被要求建议时该做什么(因为他们实际上都是顾问(或IAdvisors))

我真的希望它能帮到你。如果你不明白任何张贴评论,我会再试一次。

在面向对象语言中,多态性允许通过同一个接口处理和处理不同的数据类型。例如,考虑c++中的继承: 类B派生自类A。类型为A*的指针(指向类A的指针)可以用来处理类A的对象和类B的对象。

如果你想想这个词的希腊词根,它就会变得很明显。

Poly = many: polygon = many-sided, polystyrene = many苯乙烯(a), polyglot =多种语言,等等。 Morph =变化或形式:形态学=对生物形态的研究,Morpheus =希腊梦之神,可以变成任何形式。

因此,多态性是(在编程中)为不同的底层形式(数据类型)提供相同接口的能力。

例如,在许多语言中,整数和浮点数都是隐式多态的,因为你可以加、减、乘等等,而不管它们的类型是否不同。在通常的术语中,它们很少被视为对象。

但是,以同样的方式,像BigDecimal、Rational或Imaginary这样的类也可以提供这些操作,尽管它们操作的数据类型不同。

典型的例子是Shape类和所有可以从它继承的类(正方形、圆形、十二面体、不规则多边形、splat等等)。

对于多态性,每个类都有不同的底层数据。一个点形状只需要两个坐标(当然假设它是在二维空间中)。圆需要圆心和半径。一个正方形或矩形的左上角和右下角需要两个坐标,(可能)还需要一个旋转。一个不规则的多边形需要一系列的线。

通过使类对其代码和数据负责,您可以实现多态性。在这个例子中,每个类都有自己的Draw()函数,客户端代码可以简单地这样做:

shape.Draw()

为了得到任何形状的正确行为。

这与旧的处理方法相反,旧的方法中代码与数据是分开的,并且您将拥有像drawSquare()和drawCircle()这样的函数。

面向对象、多态和继承都是密切相关的概念,了解它们至关重要。在我漫长的职业生涯中,有许多“银弹”基本上都失败了,但OO范例已经被证明是一个很好的范例。学习它,理解它,爱上它——你会为你所做的感到高兴:)


(a)我最初写这个是作为一个笑话,但它被证明是正确的,因此,并不那么有趣。单体苯乙烯是由碳和氢组成的,C8H8,聚苯乙烯是由(C8H8)n组成的。

也许我应该说明,息肉是字母p的多次出现,尽管现在我必须解释这个笑话,即使这似乎也不好笑。

有时候,你应该在落后的时候就放弃:-)