什么是多态,它是什么,以及它是如何使用的?

时间:2009-06-23 08:14:22

标签: oop polymorphism computer-science

什么是多态,它是什么,以及它是如何使用的?

28 个答案:

答案 0 :(得分:509)

如果你想到这个词的希腊词根,它应该是显而易见的。

  • Poly = many:polygon =多边,polystyrene =许多styrenes (a),polyglot =多种语言,依此类推。
  • 变形=变化或形成:形态=研究生物形态,Morpheus =希腊梦之神能够采取任何形式。

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

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

但是,同样地,类似BigDecimalRationalImaginary的类也可以提供这些操作,即使它们在不同的数据类型上运行。

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

使用多态,这些类中的每一个都将具有不同的基础数据。点形状只需要两个坐标(假设它当然在二维空间中)。圆圈需要一个圆心和半径。正方形或矩形需要两个坐标用于左上角和右下角以及(可能)旋转。不规则多边形需要一系列线条。

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

shape.Draw()

获取任何形状的正确行为。

这与旧的处理方式形成鲜明对比,在这种方式中,代码与数据分开,并且您将拥有drawSquare()drawCircle()等功能。

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


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

也许我应该说息肉是p字母的多次出现,虽然现在我不得不解释这个笑话,即使这看起来也不好笑。

有时候,你应该在你落后时退出: - )

答案 1 :(得分:231)

多态性是指您可以将对象视为某种东西的通用版本,但是当您访问它时,代码会确定它的确切类型并调用相关代码。

这是C#中的一个例子。在控制台应用程序中创建四个类:

public abstract class Vehicle
{
    public abstract int Wheels;
}

public class Bicycle : Vehicle
{
    public override int Wheels()
    {
        return 2;
    }
}

public class Car : Vehicle
{
    public override int Wheels()
    {
        return 4;
    }
}

public class Truck : Vehicle
{
    public override int Wheels()
    {
        return 18;
    }
}

现在在控制台应用程序的模块的Main()中创建以下内容:

public void Main()
{
    List<Vehicle> vehicles = new List<Vehicle>();

    vehicles.Add(new Bicycle());
    vehicles.Add(new Car());
    vehicles.Add(new Truck());

    foreach (Vehicle v in vehicles)
    {
        Console.WriteLine(
            string.Format("A {0} has {1} wheels.",
                v.GetType().Name, v.Wheels));
    }
}

在这个例子中,我们创建了一个基类Vehicle的列表,它不知道每个子类有多少个轮子,但是知道每个子类负责知道它有多少个轮子

然后我们将自行车,汽车和卡车添加到列表中。

接下来,我们可以循环遍历列表中的每个Vehicle,并对它们进行相同的处理,但是当我们访问每个Vehicle'Wheels'属性时,Vehicle类会将该代码的执行委托给相关的子类。

这段代码被认为是多态的,因为执行的确切代码是由运行时引用的子类决定的。

我希望这会对你有所帮助。

答案 2 :(得分:190)

来自Understanding and Applying Polymorphism in PHP,谢谢Steve Guidetti。

  

多态性是一个非常简单的概念。

     

多态性描述了面向对象编程中的模式,其中类在共享公共接口时具有不同的功能。

     

多态的优点在于,使用不同类的代码不需要知道它正在使用哪个类,因为它们都以相同的方式使用。   多态性的现实世界类比是一个按钮。每个人都知道如何使用按钮:你只需对它施加压力。然而,按钮“做什么”取决于它所连接的内容以及使用它的上下文 - 但结果不会影响它的使用方式。如果你的老板告诉你按一个按钮,你已经掌握了执行任务所需的所有信息。

     

在编程领域,多态性用于使应用程序更具模块性和可扩展性。您可以根据需要创建可互换的对象,而不是描述不同操作过程的混乱条件语句。这是多态性的基本目标。

答案 3 :(得分:53)

如果有人对这些人说过CUT

  1. 外科医生
  2. 发型师
  3. 演员
  4. 会发生什么?

    • 外科医生会开始做切口。
    • 发型师会开始剪掉某人的头发。
    • 演员会突然停止在现场演出, 等待导演指导。

    因此,上面的表示显示了OOP中的多态(同名,不同行为)是什么。

    如果您正在接受采访并且面试官要求您在同一个房间告诉/显示多态性的实例,请说 -

    答案 - 门/窗

    想知道如何?

    通过门/窗 - 一个人可以来,空气可以来,光可以来,雨可以来等。

    为了更好地理解它并以简单的方式我用上面的例子.. 如果您需要参考代码,请遵循以上答案。

答案 4 :(得分:29)

类比的简单解释

美国总统采用多态性。怎么样?好吧,他有很多顾问:

  1. 军事顾问
  2. 法律顾问
  3. 核物理学家(顾问)
  4. 医疗顾问
  5. 等等。
  6. 每个人只应对一件事负责:例如:

    总统不是锌涂层或量子物理专家。他并不了解很多东西 - 但他只知道一件事:如何管理这个国家。

    它与代码有点相同:关注点和责任应该与相关的类/人分开。否则你会让总统知道世界上所有的东西 - 整个维基百科。想象一下,将整个维基百科放在一个代码类中:维护它将是一场噩梦。

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

    如果总统要专门告诉人们该怎么做,那就意味着总统需要知道到底要做什么。如果总统需要自己了解具体的事情,那就意味着当你需要做出改变时,你需要在两个地方做出改变,而不仅仅是一个。

    例如,如果EPA更改了污染法律,那么当发生这种情况时:您必须更改EPA班级 以及 总统班级。在两个地方而不是一个地方更改代码可能很危险 - 因为它难以维护。

    有更好的方法吗?

    有一种更好的方法:总统不需要知道任何事情的具体细节 - 他可以要求那些专门负责这些事情的人提供最好的建议。

      

    他可以使用多态方法来管理国家。

    示例 - 使用多态方法:

    总统所做的就是要求人们为他提供建议 - 这就是他在现实生活中的实际行动 - 以及这是一位优秀的总统应该做的事情。他的顾问都有不同的反应,但他们都知道总统的意思:建议()。他有数百人流入他的办公室。实际上他们是谁并不重要。 所有总统都知道,当他要求他们提供建议时#34;他们知道如何做出相应的回应

    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
        }
    }
    

    这种方法允许总统在不知道军事资料,医疗保健或国际外交的情况下从字面上管理国家:详细信息留给专家。总统唯一需要知道的是:&#34;建议()&#34;。

    你想要什么:

    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!没有!没有!在上述情景中,总统正在做所有的工作:他知道增加部队数量和预先存在的条件。这意味着如果中东政策发生变化,那么总统将不得不改变他的命令,以及佩特雷乌斯班级。我们只需改变彼得雷乌斯班,因为总统不应该陷入这种细节之中。他不需要知道细节。他需要知道的是,如果他订购了一份订单,那么一切都将得到妥善处理。所有细节都应留给专家。

    这使得总统可以做他最擅长的事情:制定一般政策,看起来很好并打高尔夫球:P。

    如何实际实现 - 通过基类或通用接口

    简而言之,这实际上是多态性。究竟是怎么做到的?通过&#34;实现一个通用的界面&#34; 使用基类(继承) - 请参阅上面的答案,更清楚地详细说明。 (为了更清楚地理解这个概念,你需要知道接口是什么,你需要了解继承是什么。没有它,你可能会很困难。)

    换句话说,彼得雷乌斯,康迪和健康官方都将成为实施界面的课程。 - 让我们称之为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: )))

    我真的希望它对你有所帮助。如果你发表评论时没有理解任何内容,我会再试一次。

答案 5 :(得分:23)

多态性是将一类对象视为父类的能力。

例如,假设有一个名为Animal的类,以及一个名为Dog的类,它继承自Animal。多态性是将任何Dog对象视为Animal对象的能力,如下所示:

Dog* dog = new Dog;
Animal* animal = dog;

答案 6 :(得分:22)

多态性:

这是面向对象编程的概念。不同对象以自己的方式响应相同的消息的能力称为多态。

多态性是由于每个类都存在于自己的命名空间中。在类定义中指定的名称与在其外部任何位置分配的名称不冲突。对象的数据结构和对象的方法中的实例变量都是如此:

  • 正如C结构的字段位于受保护的命名空间中一样 是对象的实例变量。

  • 方法名称也受到保护。与C函数的名称不同, 方法名称不是全局符号。一个方法的名称 class不能与其他类中的方法名冲突;二 非常不同的类可以实现具有相同名称的方法。

方法名称是对象接口的一部分。当发送消息请求对象执行某些操作时,该消息将命名该对象应执行的方法。因为不同的对象可以具有相同名称的方法,所以必须相对于接收消息的特定对象来理解消息的含义。发送给两个不同对象的相同消息可以调用两种不同的方法。

多态的主要好处是它简化了编程接口。它允许建立可以在课堂上重复使用的约定。您可以重复使用相同的名称,而不是为添加到程序中的每个新函数创建新名称。编程接口可以描述为一组抽象行为,与实现它们的类完全不同。

<强>示例:

示例1:以下是用 Python 2.x 编写的简单示例。

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Dog('Lassie')]

for animal in animals:
    print animal.name + ': ' + animal.talk()

示例2:多态性在 Java 中使用方法重载和方法覆盖概念实现。

让我们考虑Car讨论多态性的例子。选择福特,本田,丰田,宝马,奔驰等品牌,一切都属于Car。

但每个人都有自己的先进功能和更先进的技术参与他们的行动。

现在让我们创建一个基本类型Car

Car.java

public class Car {

    int price;
    String name;
    String color;

    public void move(){
    System.out.println("Basic Car move");
    }

}

让我们实施福特汽车的例子。

福特将Car类型扩展为继承其所有成员(属性和方法)。

Ford.java

public class Ford extends Car{
  public void move(){
    System.out.println("Moving with V engine");
  }
}

上面的Ford类扩展了Car类,并实现了move()方法。尽管福特通过继承已经可以使用移动方法,但福特仍然以自己的方式实施了该方法。这称为方法覆盖。

Honda.java

public class Honda extends Car{
  public void move(){
    System.out.println("Move with i-VTEC engine");
  }
}

就像福特一样,本田也扩展了Car类型并以自己的方式实现了移动方法。

方法覆盖是启用多态性的重要特性。使用方法覆盖,Sub类型可以改变通过继承可用的方法的工作方式。

PolymorphismExample.java

public class PolymorphismExample {
  public static void main(String[] args) {
    Car car = new Car();
    Car f = new Ford();
    Car h = new Honda();

    car.move();
    f.move();
    h.move();

  }
}

多态性示例输出:

在PolymorphismExample类主方法中,我创建了三个对象 - 汽车,福特和本田。所有三个对象都由Car类型引用。

请注意这里的重点是超类类型可以引用Sub类类型的对象,但反之亦然。原因是超类的所有成员都可以使用继承来使用子类,并且在编译期间,编译器会尝试评估我们使用的引用类型是否具有他试图访问的方法。

因此,对于PolymorphismExample中的引用car,f和h,移动方法存在于Car类型中。因此,编译器通过编译过程没有任何问题。

但是当涉及运行时执行时,虚拟机会调用作为子类型的对象的方法。因此,方法move()从它们各自的实现中调用。

因此,所有对象都是Car类型,但在运行时,执行依赖于调用发生的Object。这称为多态。

答案 7 :(得分:12)

通常,这指的是类型A的对象的行为类似于B类对象的能力。在面向对象的编程中,这通常通过继承来实现。一些维基百科链接阅读更多:

编辑:修复损坏的链接。

答案 8 :(得分:9)

多态性是这样的:

class Cup {
   int capacity
}

class TeaCup : Cup {
   string flavour
}

class CoffeeCup : Cup {
   string brand
}

Cup c = new CoffeeCup();

public int measure(Cup c) {
    return c.capacity
}

你可以只传递一杯而不是一个特定的实例。这有助于一般性,因为您不必为每个杯子类型提供特定的measure()实例

答案 9 :(得分:8)

(我正在浏览关于完全不同的东西的另一篇文章......并且多态性突然出现......现在我以为我知道多态性是什么......但显然不是以这种美丽的方式解释..想写下来在某个地方..更好的还是会分享它...)

http://www.eioba.com/a/1htn/how-i-explained-rest-to-my-wife

从这部分阅读:

.....多态性。这是一种令人讨厌的说法,即不同的名词可以使用相同的动词。

答案 10 :(得分:8)

我知道这是一个较老的问题,有很多好的答案,但我想包括一句话答案:

  

将派生类型视为它的基本类型。

上面有很多例子说明了这一点,但我觉得这是一个很简洁的答案。

答案 11 :(得分:4)

术语多态性来自:

poly = many

态射=改变的能力

在编程中,多态是一种“技术”,可以让你“看”一个对象是多种类型的东西。例如:

学生对象也是人物对象。如果您向学生“看”(即演员),您可能会要求提供学生证。你不能总是和一个人这样做,对吗? (一个人不一定是学生,因此可能没有学生证)。但是,一个人可能有一个名字。学生也这样做。

底线,从不同的“角度”看同一个物体可以给你不同的“视角”(即不同的属性或方法)

所以这种技术可以让你构建可以从不同角度“看”的东西。

为什么我们使用多态?对于初学者......抽象。此时应该足够的信息:)

答案 12 :(得分:4)

一般来说,它是使用相同或表面相似的API连接许多不同类型的对象的能力。有各种形式:

  • 函数重载:定义具有相同名称和不同参数类型的多个函数,例如sqrt(float),sqrt(double)和sqrt(complex)。在大多数允许这种情况的语言中,编译器会自动为传递给它的参数类型选择正确的语言,因此这是编译时多态性。

  • OOP中的虚方法:类的方法可以根据其子类的细节定制各种实现;据说这些中的每一个都覆盖了基类中给出的实现。给定一个可能是基类或其任何子类的对象,可以动态选择正确的实现,因此这是运行时多态。

  • 模板:一些OO语言的功能,其中函数,类等可以通过类型进行参数化。例如,您可以定义一个通用的“列表”模板类,然后将其实例化为“整数列表”,“字符串列表”,甚至可能是“字符串列表列表”等。通常,您为任意元素类型的数据结构编写一次代码,编译器为各种元素类型生成它的版本。

答案 13 :(得分:3)

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

Polymorphism in c++

希望它有所帮助。提取物......

  

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

Type1 x;
Type2 y;

f(x);
f(y);
  

此处,f()将执行某些操作,并将值xy作为输入。要具有多态性,f()必须能够使用至少两种不同类型的值(例如intdouble),查找并执行适合类型的代码。

(继续Polymorphism in c++

答案 14 :(得分:3)

多态性是一种物体的能力,可以采取多种形式。 例如,在人类中,当我们谈论关系时,人可以以多种形式行事。 EX:一个男人是他儿子的父亲,他是他妻子的丈夫,他是他的学生的老师。

答案 15 :(得分:3)

多态性是一种物体采取多种形式的能力。当父类引用用于引用子类对象时,OOP中最常见的多态性使用发生。在这个用Java编写的示例中,我们有三种类型的工具。我们创建三个不同的对象并尝试运行他们的轮子方法:

public class PolymorphismExample {

    public static abstract class Vehicle
    {
        public int wheels(){
            return 0;
        }
    }

    public static class Bike extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 2;
        }
    }

    public static class Car extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 4;
        }
    }

    public static class Truck extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 18;
        }
    }

    public static void main(String[] args)
    {
        Vehicle bike = new Bike();
        Vehicle car = new Car();
        Vehicle truck = new Truck();

        System.out.println("Bike has "+bike.wheels()+" wheels");
        System.out.println("Car has "+car.wheels()+" wheels");
        System.out.println("Truck has "+truck.wheels()+" wheels");
    }

}

结果是:

The Result

有关详细信息,请访问https://github.com/m-vahidalizadeh/java_advanced/blob/master/src/files/PolymorphismExample.java。我希望它有所帮助。

答案 16 :(得分:3)

让我们用一个类比。对于给定的音乐剧,每个演奏它的音乐家都会在演绎中给予她自己的触觉。

音乐家可以用界面抽象,音乐家所属的类型可以是一个抽象类,它定义了一些全局解释规则,每个演奏的音乐家都可以用具体的类建模。

如果您是音乐作品的倾听者,您可以参考该剧本,例如:巴赫的“Fuga and Tocata”以及所有演奏它的音乐家都以自己的方式进行多态化。

这只是一个可能设计的例子(在Java中):

public interface Musician {
  public void play(Work work);
}

public interface Work {
  public String getScript();
}

public class FugaAndToccata implements Work {
  public String getScript() {
    return Bach.getFugaAndToccataScript();
  }
}

public class AnnHalloway implements Musician {
  public void play(Work work) {
    // plays in her own style, strict, disciplined
    String script = work.getScript()
  }
}

public class VictorBorga implements Musician {
  public void play(Work work) {
    // goofing while playing with superb style
    String script = work.getScript()
  }
}

public class Listener {
  public void main(String[] args) {
    Musician musician;
    if (args!=null && args.length > 0 && args[0].equals("C")) {
      musician = new AnnHalloway();
    } else {
      musician = new TerryGilliam();
    }
    musician.play(new FugaAndToccata());
}

答案 17 :(得分:2)

在面向对象编程中,多态性是指编程语言根据数据类型或类以不同方式处理对象的能力。更具体地说,它是重新定义派生类的方法的能力。

答案 18 :(得分:2)

多态性是程序员根据这些对象的需要编写同名方法的能力,这些方法针对不同类型的对象执行不同的操作。例如,如果您正在开发一个名为Fraction的类和一个名为ComplexNumber的类,则这两个类都可能包含一个名为display()的方法,但每个方法都会以不同方式实现该方法。例如,在PHP中,您可以像这样实现它:

//  Class definitions

class Fraction
{
    public $numerator;
    public $denominator;

    public function __construct($n, $d)
    {
        //  In real life, you'd do some type checking, making sure $d != 0, etc.
        $this->numerator = $n;
        $this->denominator = $d;
    }

    public function display()
    {
        echo $this->numerator . '/' . $this->denominator;
    }
}

class ComplexNumber
{
    public $real;
    public $imaginary;

    public function __construct($a, $b)
    {
        $this->real = $a;
        $this->imaginary = $b;
    }

    public function display()
    {
        echo $this->real . '+' . $this->imaginary . 'i';
    }
}


//  Main program

$fraction = new Fraction(1, 2);
$complex = new ComplexNumber(1, 2);

echo 'This is a fraction: '
$fraction->display();
echo "\n";

echo 'This is a complex number: '
$complex->display();
echo "\n";

输出:

This is a fraction: 1/2
This is a complex number: 1 + 2i

其他一些答案似乎暗示多态性仅与继承一起使用;例如,也许FractionComplexNumber都实现了一个名为Number的抽象类,它有一个方法display(),然后Fraction和ComplexNumber都有义务实现。但是你没有需要继承来利用多态性。

至少在PHP这样的动态类型语言中(我不了解C ++或Java),多态性允许开发人员在不必提前知道对象类型的情况下调用方法,并相信正确的实现该方法将被调用。例如,假设用户选择Number创建的类型:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

在这种情况下,即使开发人员无法提前知道用户是选择分数还是复数,也会调用相应的display()方法。

答案 19 :(得分:2)

多态性:

  

根据类的实例执行不同的执行,而不是引用变量的类型。

接口类型引用变量可以引用实现该接口的任何类实例。

答案 20 :(得分:2)

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

考虑一个人X.

他只是一个人,但他的行为却很多。 你可能会问:如何:

他是他母亲的儿子。 朋友给他的朋友。 他妹妹的兄弟。

答案 21 :(得分:2)

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

例如, Shape 是一个界面,它有 Square Circle Diamond 子类型。现在你有了一个Square对象,你可以自动将Square转换为Shape,因为Square是一个Shape。但是当你尝试向下转换Shape到Square时,你必须进行显式类型转换,因为你不能说Shape是Square,它也可以是Circle。 因此,您需要使用Square s = (Square)shape之类的代码手动投射它,如果形状为圆形,则会得到java.lang.ClassCastException,因为圆形不是方形。

答案 22 :(得分:1)

多态性是指在给定类中使用对象的能力,其中构成对象的所有组件都由给定类的子类继承。这意味着一旦这个对象被一个类声明,它下面的所有子类(以及它们的子类,依此类推,直到你到达最远/最低的子类)继承对象及其组件(化妆)。

请记住,每个班级必须保存在单独的文件中。

以下代码举例说明了多态性:

SuperClass:

public class Parent {
    //Define things that all classes share
    String maidenName;
    String familyTree;

    //Give the top class a default method
    public void speak(){
         System.out.println("We are all Parents");
    }
}

父亲,子类:

public class Father extends Parent{
    //Can use maidenName and familyTree here
    String name="Joe";
    String called="dad";

    //Give the top class a default method
    public void speak(){
        System.out.println("I am "+name+", the father.");
    }
}

孩子,另一个子类:

public class Child extends Father {
    //Can use maidenName, familyTree, called and name here

    //Give the top class a default method
    public void speak(){
        System.out.println("Hi "+called+". What are we going to do today?");
    }
}

执行方法,引用要启动的父类:

public class Parenting{
    public static void main(String[] args) {
        Parent parents = new Parent();
        Parent parent = new Father();
        Parent child = new Child();

        parents.speak();
        parent.speak();
        child.speak();
    }
}

请注意,每个类都需要在单独的* .java文件中声明。 代码应该编译。 另请注意,您可以继续使用maidenName和familyTree。 这就是多态的概念。 这里还探讨了继承的概念,其中一个类可以使用或者由子类进一步定义。

希望这有助于并明确表达。 当我找到一台可以用来验证代码的计算机时,我会发布结果。感谢您的耐心等待!

答案 23 :(得分:1)

多态性允许相同的例程(函数,方法)作用于不同的类型。

由于许多现有的答案都将子类型与多态性混为一谈,因此这里有三种方法(包括子类型)来实现多态性。

  • 参数(通用)多态允许例程除了正常参数之外还接受一个或多个类型参数,并在这些类型上运行。
  • 子类型多态性允许例程对其参数的任何子类型执行操作。
  • Ad hoc多态通常使用例程重载来授予多态行为,但也可以引用其他多态实现。

另见:

http://wiki.c2.com/?CategoryPolymorphism

https://en.wikipedia.org/wiki/Polymorphism_(computer_science)

答案 24 :(得分:0)

什么是多态性?

多态是指以下能力:

  • 在调用特殊类型的方法而不是广义类型的方法时,仅在知道特殊类型的实例的情况下调用该特殊类型的实例的操作:它是动态多态性

  • 定义几种具有保存名称但参数不同的方法:它是静态多态性

第一个(如果是历史上的定义,则是最重要的)。

多态性是做什么用的?

它允许创建类层次结构的强类型一致性,并执行某些魔术操作,例如管理不同类型的对象列表,而无需知道它们的类型,但仅知道其父类型之一作为数据绑定。

Strong and weak typing

样本

这里有一些形状,如点,线,矩形和圆,它们的Draw()操作不带任何内容,也没有参数来设置超时以擦除它。

public class Shape
{
 public virtual void Draw()
 {
   DoNothing();
 }
 public virtual void Draw(int timeout)
 {
   DoNothing();
 }
}

public class Point : Shape
{
 int X, Y;
 public override void Draw()
 {
   DrawThePoint();
 }
}

public class Line : Point
{
 int Xend, Yend;
 public override Draw()
 {
   DrawTheLine();
 }
}

public class Rectangle : Line
{
 public override Draw()
 {
   DrawTheRectangle();
 }
}

var shapes = new List<Shape> { new Point(0,0), new Line(0,0,10,10), new rectangle(50,50,100,100) };

foreach ( var shape in shapes )
  shape.Draw();

此处Shape类和Shape.Draw()方法应标记为抽象。

他们不是要弄明白的。

说明

在不使用多态性的情况下,使用抽象虚拟覆盖在解析形状时,只有Spahe.Draw()方法被称为CLR,它不知道调用哪种方法。因此它调用我们所作用类型的方法,由于列表声明,此处的类型为Shape。因此,代码根本不执行任何操作。

有了多态性,CLR能够infer使用所谓的虚拟表来C# - Polymorphism (Level 1)作用于对象的真实类型。因此,它调用 good 方法,如果Shape为Point,则在这里调用Shape.Draw()调用Point.Draw()。因此,代码绘制了形状。

更多阅读内容

Polymorphism in Java (Level 2)

Polymorphism (C# Programming Guide)

Virtual method table

{{3}}

答案 25 :(得分:0)

多态性使您能够创建一个调用另一个模块的模块,并且具有针对控制流而不是控制流的编译时依赖性点。

通过使用多态,高级模块不依赖于低级模块。两者都取决于抽象。这有助于我们应用依赖性倒置原则(https://en.wikipedia.org/wiki/Dependency_inversion_principle)。

这是我找到上述定义的地方。大约50分钟后,教练解释了上述内容。 https://www.youtube.com/watch?v=TMuno5RZNeE

答案 26 :(得分:0)

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

答案 27 :(得分:0)

编码术语中的多态性是指您的对象可以通过继承等存在为多个类型。如果您创建一个名为“Shape”的类来定义对象所具有的边数,那么您可以创建一个继承它的新类。作为“广场”。当您随后创建“Square”实例时,您可以根据需要将其从“Shape”转发回“Square”。