多态-仅用两个句子定义


85

我查看了其他定义和解释,但没有一个让我满意。我想看看是否有人可以在不使用任何代码或示例的情况下最多在两个句子中定义多态性。我不想听到“所以你有一个人/汽车/开罐器...”或这个词是如何衍生的(没人知道您知道poly和morph意味着什么)。如果您对多态性有一个很好的掌握,并且英语水平很好,那么您应该能够以简短而密集的定义回答这个问题。如果您的定义准确地定义了多态性,但它的密度如此之高以至于需要进行多次读取,那么这正是我要寻找的。

为什么只有两个句子?因为定义简短而智能。解释很长,其中包含示例和代码。在这里寻找解释(这些页面上的答案对我的问题并不满意):

多态性vs覆盖vs重载
尝试尽可能简单地描述多态性

我为什么要问这个问题?因为有人问我同样的问题,所以我无法给出令人满意的定义(按照我的标准,这是很高的标准)。我想看看这个网站上有没有头脑的人能做到这一点。

如果您真的不能满足两个句子的要求(这是很难定义的主题),那么您过去就可以了。这个想法是要有一个定义,该定义实际上定义什么是多态性,而不解释它的用途或用法(得到差异吗?)。


一个名字,多个实现。
Prosunjit Biswas

2
我在求职面试中被问到了这个问题。我觉得在求职面试中问这个问题是一种卑鄙的势利行为,这是Google员工会自鸣得意地提出的一种假设,即没人能有效回答。如果您因为无法回答而没有找到工作,那么最好是为那些对自己的工作更感兴趣而不是比自己更聪明的人工作。
MagicLAMP

多态是在开发中要理解的非常重要的概念。我强烈建议至少了解它的价值(如果不是正式定义)。我建议至少能够解释一下策略模式的工作原理及其价值。
乍得·约翰逊

Answers:


106

多态性允许表达某种合同,可能有许多类型以不同的方式(无论是否通过类继承)实现该合同,每种类型均根据自己的目的。使用该合同的代码不必(*)关心所涉及的实现,而只是遵守合同。

(*)无论如何,在理想情况下-显然,调用代码经常是非常故意地选择了合适的实现!


1
马克,您有一次接受了这个答案,然后又拒绝了吗?我正在尝试找出信誉系统中看起来像是个错误的东西-这个答案今天给了我-15代表的净收入,这很奇怪。
乔恩·斯基特

同样,乔恩(Jon)-我现在有2个具有-15代表的答案。我不在乎,但这很有趣。
2009年

3
严格来说,没有要求“一种类型表示某种合同”。真正需要做的就是,多个实现可以响应同一条消息,而消息发件人无需知道或关心哪个实现正在处理该消息。
Doug Knesek

3
@Doug:如果没有合同,甚至没有通过文档或命名暗示的合同,那么您到底知道它将如何做您想做的事情?您在自己的答案中谈论的是“界面”,这听起来像是我的合同,您认为两者之间的区别是什么?“接口”和“合同”都是可以在“强”意义上(例如在编译时强制执行)或非常宽松(例如通过命名约定和使用动态类型)使用的词。
乔恩·斯基特

1
@Alex:是的,那是我将要进行的编辑-我更喜欢我的措辞。您始终可以添加自己的答案。
乔恩·斯基特

72

通常可以吃水果,但是以不同的方式吃不同类型的水果。可以吃一个苹果,是一种水果(因为它是一种水果)。香蕉也可以吃(因为它也是一种水果),但是与苹果的食用方式不同。你先剥皮。

好吧,至少我知道,但是我有些奇怪,所以我知道些什么。

这说明了继承(可以吃水果),多态(吃水果的东西可以吃所有类型的水果)和封装(香蕉有皮)。

严肃地说,对象继承,多态性,封装,虚拟事物,抽象事物,私有事物,公共事物,这些都是硬概念。如果某人绝对希望对此有2个句子的定义,那么请将该问题标记为代码高尔夫变体,因为两个这样的句子必须非常简洁,除非您知道它已经是什么,否则您将学不到足够的知识它知道您需要了解更多信息。


lassevk:“除非您知道它已经是什么,否则您将不足以了解它需要了解更多信息。” <<只是为了澄清,这就是我所期望的。我正在寻找一个可能需要一些思考才能理解的定义。没有人会用来教初学者。
Mark Testa

2
我收集到的信息,我只是发布了一个幽默(无论如何对我来说都是这样)的答案:)多态性和OOP是其中的一大难题,如果您绘制学习曲线图,就会碰到一堵大难题,然后要么爬上它,或者您不这样做。如果这样做,那么您通常会拥有很大的AHA!经验...
Lasse V. Karlsen

8
铁杉也是水果!您可以只吃一次!
詹姆斯·安德森

@JamesAnderson那么,单身人士吗?
Lasse V. Karlsen

47

多态性声明了一个不知道类型的统一接口,将实现细节留给了实现该接口的具体类型。


这简明扼要,我认为它非常适合
Alex W


21

实际上,有多种形式的多态性,对此存在很多争议。您甚至可能会看到CS教授无法正确定义它。我知道三种类型:

  • 临时多态性(看起来像鸭子,走路像鸭子=>是鸭子)。例如,可以在Haskell和Python中看到。

  • 通用多态性(类型是某个通用类型的实例)。例如可以在C ++中看到(int的向量和string的向量都具有成员函数的大小)。

  • 子类型多态(一种类型从另一种类型继承)。可以在大多数OO编程语言中看到(即Triangle is a Shape)。


2
+1表示存在不同类型的多态性。但是,您对即席多态性的定义似乎与en.wikipedia.org/wiki/Type_polymorphism中提到的定义完全不同。该页面上说有2种类型(即席与参量),而不是3种,并且还区分了多态函数和多态数据类型。据我所确定,您的3种类型分别对应于参数多态函数,参数多态数据类型和即席多态函数。
劳伦斯·贡萨尔维斯(Lawrence Gonsalves),2009年

嗨,这些“似乎是通用类型的实例”与“来自另一种类型的继承”之间的区别是什么?
Shanimal

@LaurenceGonsalves,请注意,第一个注释中提供的链接确实指向三种类型。参数多态性定义为允许“通用”编写函数或数据类型。
Shanimal

14

我真的很明白,为什么你问这个问题。我了解多态,但是我正在接受工作面试,并被要求给出简短而清晰的多态定义。因为我无法给出清晰简短的定义,所以我开始考虑它,这是我的定义:

一种类型的对象具有一个相同接口的能力,但是该接口的实现方式不同。


10

定义

多态性是表示$ 1想法的$ 10单词-当我要求完成某件事时,只要最终结果合适,我就不在乎如何实现。只要服务的提供正确的,我不关心关于落实

讨论区

尽管多态性通常用于软件开发中,尤其是在遵循面向对象原理开发的系统中,但是从根本上讲,多态性是一种真实世界的原理,应该以真实世界的术语(而不是技术术语)进行定义。

例子

当我想打电话时,我拿起电话,拨一个号码,然后与另一方通话。我不在乎手机的制造者,使用的技术,有线,无线,移动或VOIP或保修范围。

当我要打印文档时,我将其打印。我不在乎实施语言,打印机品牌,连接方式,耗材选择或纸张质量。


5
听起来像是Encapsulation我的榜样
Singleton 2010年

1
多态性,封装和抽象都紧密相关,尽管它们关注的是不同的观点。好的抽象使多态性更容易实现,好的封装有助于防止细节“泄漏”。
Bevan 2010年


8

多态是在设计对象模型时使用的面向对象策略,以帮助简化代码。多态性的核心是定义两个相似但不同的对象,然后将这两个对象视为相同的能力。

好的,很难。


7

我只是想补充一下我对多态性的解释:从广义上讲,多态性是为不同类型的实体提供单一接口的行为。

这是相当通用的,但是这是我想到包装我所知道的所有三种多态性的唯一方法:即席参数化子类型。我将在下面详细介绍,并按名称(按字母顺序)对多态类型进行排序。您感兴趣的一个可能是亚型多态,这是最后一个。

临时多态性

临时多态性是为不同参数类型提供同一方法的多个实现的动作。在OOP中,通常称为方法重载。例如:

public String format(int a) {
    return String.format("%2d", a);
}

public String format(Date a) {
    return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(a);
}

两种format方法共享一个接口,但是它们可用于不同类型的实体。

参数多态性

参数多态性是使类(或方法)在本身就是类(或方法)的参数的类型上工作的行为。它通常称为泛型

例如,Java的List[T]期望T在实例化时有一个参数,而该参数定义了结果对象的类型。

对于纯粹主义者,请注意,我故意忽略原始类型,因为在这种情况下,它们只会使水变得混乱。

List[String]List[Date]共享一个接口,但可以使用(和使用)不同的类型

亚型多态性

子类型多态性可能是您最初在问题中要表达的意思:这是为单个相同类型的多个实现提供单个接口的行为。

使用习惯示例:Animal提供所有实现都必须遵守的合同。DogAnimal,因此支持所有Animal声明的操作。根据Liskov替换原则,这允许您使用需要实例Dog的实例Animal(但不能相反)。

如果CatDog都是的子类Animal,则它们共享一个接口,但实际上是不同的类型

我在这里有点切线,但是(我认为)子类型多态是唯一允许覆盖的子类型:重新定义由父类定义的方法的行为。这通常与重载混淆,正如我们之前所看到的,重载是一种多态性,实际上不需要子类化(实际上也不需要类)。


那么基于接口的多态性呢?
siamak 2014年

@siamak是不是父类型完全是抽象的特定子类型多态性?还是您还有其他意思?
Nicolas Rinaudo 2014年

我对接口的意图是将接口作为面向对象语言中存在的引用类型,如下所示:接口I1 {void M();}我确实认为子类型或基于继承的多态性与基于接口的多态性之间有太多差异。因为类型之间基于继承的多态性之间存在“ Is-a”关系,但是在基于接口的多态性中则没有这种关系。实际上,可以在各种不同类型(类)之间共享具有不同实现的相同行为
siamak 2014年

我必须承认我很困惑-除了您对上壳体的某种弹道方法之外,似乎您对所谓的基于接口的多态性的描述与我对子类型多态性的描述完全相同。我敢肯定,您会看到与众不同的地方,但恐怕我确实不清楚。
Nicolas Rinaudo 2014年

如您所见,汽车与鸟和人之间没有任何关系,但它们可以以自己的方式移动。抽象类和接口之间存在巨大差异,并且使用接口与子类型化是不同的,因此在我看来,继承多态和基于接口的多态不是同一事物,也不相等。//很难,在注释段中编码//
siamak 2014年

6

似乎这里提供了最好的定义,因此,请允许我添加我的两分钱,仅供其他观察者使用。我希望它可以提供更多帮助。

有两种多态性:

1. Compile-time (static) polymorphism or (ad hoc) polymorphism.

那就是方法重载和运算符重载

2.  Run time or (dynamic) polymorphism.

第一个术语是从Java和C ++术语继承的。

但是在.NET术语中,只有第二个我是指运行时多态)实际上被认为是多态,简称为多态

据我所知,有三种实现(运行时多态性的方法

 1. Parametric polymorphism or simply the use of generics (templates in C++).

 2. Inheritance-based polymorphism or subtyping.

 3. Interface-based polymorphism.

基于接口的多态性的一个简单示例:

interface Imobile
{
    void Move();
}

class Person :Imobile
{
    public void Move() { Console.WriteLine("I am a person and am moving in my way."); }
}

class Bird :Imobile
{
    public void Move() { Console.WriteLine("I am a bird and am moving in my way."); }
}

class Car :Imobile
{
    public void Move() { Console.WriteLine("I am a car and am moving in my way."); }
}


class Program
{

    static void Main(string[] args)
    {
        // Preparing a list of objects
        List<Imobile> mobileList = new List<Imobile>();

        mobileList.Add(new Person());
        mobileList.Add(new Bird());
        mobileList.Add(new Car());

        foreach (Imobile mobile in mobileList)
        {
            mobile.Move();
        }

        // Keep the console open
        Console.WriteLine("Press any key to exit the program:");
        Console.ReadKey();
    }
}

输出:

 I am a person and am moving in my way.
 I am a bird and am moving in my way.
 I am a car and am moving in my way.
 Press any key to exit the program:

我仍然看不到您的改变。人,鸟和汽车都是Imobile的子类型。人是Imobile,Bird是Imobile,而Car是Imobile。如果需要类型为Imobile的变量,则可以使用Person,Bird或Car的实例,所有实例都将输入check。这正是亚型多态性的含义。
Nicolas Rinaudo 2014年

Bird和Person和Car不是Imobile的子类型,它们是该接口的实现者,并且以自己的方式“实现”该接口。“子类型”一词在实类型和从其继承的实子类型之间广泛使用,在这种情况下,它们之间存在“ Is-a”关系,例如,狗是哺乳动物的亚型。
siamak 2014年

从编译器的角度来看,引用接口并使用引用是正确的。/ BUT / IT在继承关系中具有子类型并不是一个相等的概念。而且我认为将接口的实现者称为子类型是如此尴尬,而且确实不正确。
siamak

一个基于继承的多态性的例子很好地阐述了这个答案。
马塞洛·梅森

5

多态是一种软件编码的抽象,其中几个不同的基础实体(通常是数据,但总是存在)共享一个公共接口,从而使它们在运行时看起来和行为相同。我们使用此技术作为开发技术,以绝对最小的实现在各种相似但不完全相同的实例上实施一致的行为,从而降低了对错误和不一致的期望。

保罗


5

多态==多个类+相同的方法签名+特定于类的行为。




2

多态是对象针对同一调用出现和表现不同的能力。例如:每只动物的出现和声音都不同(当您击中它时:))



1

为不同类型的一组类似操作指定一个名称。如果做得好,这个类比很明显,例如,算术上“加”数字,并通过串联(加和它们的长度)“加”字符串。


1

这是我一直遵循的定义:

如果两个对象都以相同的语义响应相同的消息,则它们之间是多态的(相对于特定协议而言)。

多态性与消息有关,是关于能够以相同的语义响应相同的消息集。

如果两个对象可以响应为空?但是消息的语义不同,那么它们不是多态的。



1

多态是一种编程功能,它允许对象具有多种类型(“形状”),并允许您根据需要执行的操作将其视为这些类型中的任何一种,而无需了解或关心其其他类型。


1

多态是语言功能,允许高级算法代码在多种类型的数据上保持不变。 还有另一句话,不管是什么意思;

(C ++支持的类型在我的答案中列出并进行了对比:c ++中的多态性


0

多态性概念最近成为一种现象。这是实际的漂移。运行时定义了哪个子方法应该由超类的引用调用。现在,实际上意味着什么?这实际上没有任何意义。您可以简单地进行编码而无需多态。所以为什么?因为,如果我们没有多态性,就必须记住所有的子类函数定义。在实践中,多态使我们摆脱了这种情况。

您可以如下定义列表:

List list = new List();

但是,如果您检查IList,则可以从以下方面受益:

IList list = new List();

IList自由使用参考。假设IList在另一个类中也实现了该类,则可以通过再次IList引用来使用该未知类的方法,而无需尝试记住该类的名称。很棒,不是吗?

现在,更多有价值的信息即将到来:
Java默认是多态的,而.NET和C ++不在MS中,您必须声明基本函数virtual(以及.NEToverride关键字)。

另外,多态性中有2个积分规则。一种是继承(通过接口隐式或通过类扩展),而另一种是重写。没有覆盖,多态就不存在。请注意,方法重载(总是在单个类中)也是一种“最小化”多态性。


1
那是超过两个句子。
危险的

0

对于给定的方法签名,为不同的,与层次相关的类运行不同的方法实现。


0

多态性是指使用不同的类以一种通用的方式实现一个通用接口(或扩展一个通用的基类)的能力,而无需现在的特定实现,并且仅使用通用接口中可用的方法。

即:在Java中,由于ArrayList和LinkedList都实现了List,所以如果将变量声明为List,则无论变量是实例为ArrayList还是LinkedList,都可以始终执行List中允许的操作。


0

相同类型的实体(即,实现相同的接口或从相同的类派生)的行为方式不同(在相同的方法名称下)。


0

我认为在不同类中实现具有相同签名的方法(具有某种继承关系,无论是使用扩展还是实现)都是方法重写和多态性,因为这样我们就可以实现多种形式的相同方法签名。


-2

我猜有时候对象是动态调用的。您不确定对象是否是经典形状的多边形中的三角形,正方形等。例。

因此,为了抛弃所有这些东西,我们只调用派生类的函数,并假定将调用动态类之一。

您不在乎它是方形,三角形还是矩形。您只关心该区域。因此,将根据传递的动态对象来调用getArea方法。


-2

多态是一种功能,可以自动适应接受不同数据类型的输入数据的能力。您可以“添加”两个双打的“ 1.1”和“ 2.2”,并获得“ 3.3”或“添加”两个字符串“ Stack”和“ Overflow”,并获得“ StackOverflow”。


为什么有人将其标记为低-这是National Instruments网站上有关多态的“字面答案”!
2015年

-3

多态是指不同的对象以不同的方式响应相同的方法。例如,当人在道路上行走时,汽车在道路上移动。这是两个对象以不同的方式响应同一条道路。


实际上,多态性将不同类的实例视为通用类型,并且能够独立于不同类如何实现这些方法而使用在该通用类型中声明的方法。
加拉帕塔2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.