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

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

551095 次浏览

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

编辑:固定破碎的链接。

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

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

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

让我们打个比方。对于一个特定的音乐剧本,每个演奏它的音乐家都有自己的诠释。

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

如果你是音乐作品的听众,你可以参考剧本,例如巴赫的“富加与托卡塔”,每个演奏它的音乐家都以自己的方式多态地演奏。

这只是一个可能的设计示例(在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());
}
在面向对象语言中,多态性允许通过同一个接口处理和处理不同的数据类型。例如,考虑c++中的继承: 类B派生自类A。类型为A*的指针(指向类A的指针)可以用来处理类A的对象和类B的对象

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

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

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

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

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

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

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

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

shape.Draw()

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

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

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


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

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

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

多态性一词来自:

形态性=改变的能力

在编程中,多态性是一种“技术”,它允许您将一个对象“看作”不止一种类型的事物。例如:

学生对象也是人对象。如果你“看”这个学生,你可能会问他要学生证。你不能总是对一个人这么做,对吧?(一个人不一定是学生,因此可能没有学生证)。然而,每个人可能都有名字。学生也一样。

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

因此,这种技术可以让你构建可以从不同角度“观察”的东西。

为什么我们使用多态性?首先……抽象。在这一点上,它应该是足够的信息:)

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

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

  • OOP中的虚方法:一个类的方法可以有各种实现,以适应其子类的具体情况;每一个都被认为是覆盖基类中给出的实现。给定一个对象,该对象可能是基类或其任何子类,将动态地选择正确的实现,因此这就是运行时多态。

  • 模板:一些面向对象语言的特性,函数、类等可以通过类型参数化。例如,你可以定义一个通用的“list”模板类,然后实例化它为“整数列表”,“字符串列表”,甚至可能是“字符串列表的列表”等等。通常,对于任意元素类型的数据结构,只需编写一次代码,编译器就会为各种元素类型生成相应的版本。

多态性是程序员编写同名方法的能力,这些方法根据对象的需要,为不同类型的对象做不同的事情。例如,如果您正在开发一个名为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()方法,尽管开发人员无法提前知道用户将选择分数还是复数。

多态性是:

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
}

你可以只传递一个Cup而不是一个特定的实例。这在一般情况下很有帮助,因为您不必为每个cup类型提供特定的measure()实例

在编码术语中,多态性是指您的对象可以通过继承等方式以多种类型存在。如果你创建了一个名为“Shape”的类,它定义了对象的边数,那么你可以创建一个继承它的新类,如“Square”。当你随后创建一个“Square”实例时,你可以根据需要将它从“Shape”前后转换为“Square”。

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

下面是一个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,并将它们都视为相同的,但是当我们访问每个Vehicles 'Wheels'属性时,Vehicle类将该代码的执行委托给相关的子类。

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

我希望这对你有所帮助。

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

c++中的多态性

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

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

Type1 x;
Type2 y;


f(x);
f(y);

在这里,f()执行一些操作,并被赋予值xy作为输入。要成为多态的,f()必须能够操作至少两种不同类型的值(例如intdouble),找到并执行适合类型的代码。

(继续到c++中的多态性)

来自在PHP中理解和应用多态性,感谢Steve Guidetti。

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

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

多态性的美妙之处在于,使用不同类的代码不需要知道它使用的是哪个类,因为它们都是以相同的方式使用的。 在现实世界中,与多态性类似的是按钮。每个人都知道如何使用按钮:你只需按一下按钮。然而,按钮“做什么”取决于它连接的对象和使用它的上下文,但结果并不影响它的使用方式。如果你的老板告诉你按一个按钮,你已经有了完成这项任务所需的所有信息

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

我知道这是一个有很多好答案的老问题,但我想用一句话来回答:

将派生类型视为其基类型。

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

# EYZ0

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

多态性源于每个类都存在于自己的名称空间中。在类定义中赋值的名称与在类定义之外赋值的名称不冲突。对象数据结构中的实例变量和对象的方法都是这样:

  • 正如C结构的字段在受保护的名称空间中,因此 是对象的实例变量。

  • 方法名也受保护。与C函数名不同, 方法名不是全局符号。其中一个方法的名称 类不能与其他类中的方法名冲突;两个

  • .

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

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

例子:

下面是一个用EYZ1编写的简单示例。

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()

多态性在Java中使用方法重载和方法压倒一切的概念实现。

让我们以Car为例来讨论多态性。比如福特、本田、丰田、宝马、奔驰等品牌,都是汽车类型。

但每一个都有自己的高级功能和更先进的技术涉及到他们的移动行为。

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

Car.java

public class Car {


int price;
String name;
String color;


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


}

让我们实现Ford Car的例子。

Ford扩展Car类型以继承其所有成员(属性和方法)。

Ford.java

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

上面的Ford类扩展了Car类,也实现了move()方法。尽管Ford已经通过继承可以使用move方法,但Ford仍然以自己的方式实现了该方法。这称为方法重写。

Honda.java

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

就像Ford一样,Honda也扩展了Car类型,并以自己的方式实现了move方法。

方法重写是启用多态性的一个重要特性。使用方法重写,子类型可以更改通过继承可用的方法的工作方式。

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, Ford和Honda。这三个对象都是由Car类型引用的。

请注意一个重要的一点,超类类型可以引用对象的子类类型,但反之则不可能。原因是父类的所有成员都可以通过继承对子类可用,并且在编译期间,编译器会尝试评估我们正在使用的引用类型是否具有他试图访问的方法。

因此,对于多态例子中的引用car,f和h, move方法存在于car类型中。因此,编译器通过编译过程没有任何问题。

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

因此,所有对象都是Car类型的,但在运行时,执行取决于调用所发生的对象。这就是所谓的多态性。

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

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

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

下面的代码演示了多态性:

# EYZ0 < / >强

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");
}
}

# EYZ0 < / >强

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.");
}
}

# EYZ0 < / >强

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?");
}
}

# EYZ0 < / >强

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。 这就是多态性的概念。 这里还探讨了继承的概念,其中可以使用一个类,或者由子类进一步定义

希望这有助于并使它清楚。 当我找到一台我可以用来验证代码的计算机时,我会发布结果。谢谢您的耐心等待!< / p >

我正在浏览另一篇完全不同的文章。多态性出现了……现在我认为我知道多态性是什么....但显然不是用这种美丽的方式解释的。想把它写在某个地方。更好的是分享它…)

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

从这部分开始阅读:

…多态性。这是一种很奇怪的说法,不同的名词可以有相同的动词。

多态性是对象的一种能力,可以有多种形式。 例如,在人类课堂上,当我们谈论关系时,一个人可以表现为多种形式。 男人对儿子是父亲,对妻子是丈夫,对学生是老师。< / p >

如果有人对这些人说CUT

  1. 外科医生
  2. 发型师
  3. 这个演员

会发生什么?

  • 外科医生开始做一个切口。
  • 发型师会开始给某人理发。
  • 演员会突然停止在当前场景之外的表演, 等待导演指导。

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

如果你要去参加面试,面试官要求你在我们坐在的同一个房间里讲述/展示一个多态性的生动例子,比如说-

答案-门/窗

想知道吗?

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

为了更好地理解它,我用了上面的例子。 如果你需要代码参考,请参考上面的答案

# EYZ0

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

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

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

假设一个人X。

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

他就像他母亲的儿子。 朋友对朋友。

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

例如,形状是一个接口,它有广场钻石子类型。现在你有了一个正方形对象,你可以自动将正方形转换为形状,因为正方形是一个形状。但当你尝试将Shape向下转换为Square时,你必须进行显式类型转换,因为你不能说Shape是Square,它也可以是Circle。 所以你需要用Square s = (Square)shape这样的代码手动转换它,如果形状是圆形,你会得到java.lang.ClassCastException,因为圆形不是正方形

多态性是一个对象具有多种形式的能力。在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。我希望这能有所帮助。

简单类比解释

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

  1. 军事顾问
  2. 法律顾问
  3. 核物理学家(作为顾问)
  4. 等等。

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

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

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

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

如果总统明确地告诉人们要做什么,这将意味着总统需要知道确切地告诉人们要做什么。如果总统自己需要知道特定的事情,这意味着当您需要做出更改时,那么您需要在< /强> < >强两个地方中进行更改,而不仅仅是在< /强> < >强两个地方中。

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

有没有更好的方法?

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

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

使用多态方法的例子:

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

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();
}
}

不!不!不!在上面的场景中,总统正在做所有的工作:他知道增加部队人数和已有的条件。这意味着如果中东政策改变,那么总统将不得不改变他的命令,还有彼得雷乌斯班也是如此。我们只需要改变彼得雷乌斯类,因为总统不应该陷入那种细节。他不需要知道细节。他只需要知道,只要他下了单,一切都会得到妥善处理。所有的细节都应该留给专家。

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

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

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

换句话说,彼得雷乌斯、赖斯和卫生官员都将是“实现接口”的阶层。让我们称它为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))

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

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

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

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

参见:

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

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

多态性使您能够创建一个模块调用另一个模块,并且在编译时依赖于控制流而不是控制流。

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

这是我找到上面定义的地方。在视频中大约50分钟,教练解释了上述内容。 # EYZ0 < / p >

什么是多态性?

多态性是一种能力:

  • 在调用专门化类型的方法时调用专门化类型的方法,而不调用广义类型的方法,从而调用对专门化类型实例的操作:

    这是动态多态性

  • 定义几个具有保存名称但参数不同的方法:

    这是静态多态性

首先是历史定义,也是最重要的。

多态用于什么?

它允许创建类层次结构的强类型一致性,并做一些神奇的的事情,比如管理不同类型的对象列表,而不知道它们的类型,只知道它们的父类型之一,以及数据绑定。

强弱类型

样本

这里有一些形状,如点、线、矩形和圆,它们的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能够使用所谓的虚拟表推断出我们所操作的对象的真实类型。因此它调用方法,这里调用Shape. draw()如果Shape是Point则调用Point. draw()。所以代码画出了形状。

更多的阅读

c# -多态性(一级)

Java多态(Level 2) . b

多态性(c#编程指南)

虚方法表