什么是多态性,它的用途是什么,它是如何使用的?
如果您考虑该术语的希腊词根,它应该变得显而易见。
Poly = many:多边形 = 多面,聚苯乙烯 = 许多苯乙烯 (a),polyglot = 多种语言,依此类推。
Morph = 变化或形式:形态 = 研究生物形式,Morpheus = 希腊的梦之神,能够采取任何形式。
因此,多态性是(在编程中)为不同的底层形式(数据类型)呈现相同接口的能力。
例如,在许多语言中,整数和浮点数是隐式多态的,因为您可以进行加法、减法、乘法等,而不管类型是否不同。通常,它们很少被视为对象。
但是,以同样的方式,像 BigDecimal
或 Rational
或 Imaginary
这样的类也可以提供这些操作,即使它们对不同的数据类型进行操作。
经典示例是 Shape
类和所有可以从它继承的类(正方形、圆形、十二面体、不规则多边形、splat 等)。
使用多态性,这些类中的每一个都将具有不同的基础数据。一个点形状只需要两个坐标(当然假设它在二维空间中)。圆需要一个圆心和一个半径。正方形或矩形需要左上角和右下角的两个坐标以及(可能)旋转。一个不规则的多边形需要一系列的线。
通过让类对其代码和数据负责,您可以实现多态性。在此示例中,每个类都有自己的 Draw()
函数,客户端代码可以简单地执行以下操作:
shape.Draw()
获得任何形状的正确行为。
这与代码与数据分离的旧方式形成鲜明对比,您将拥有诸如 drawSquare()
和 drawCircle()
之类的函数。
面向对象、多态性和继承都是密切相关的概念,了解它们至关重要。在我漫长的职业生涯中,有许多“灵丹妙药”基本上都以失败告终,但 OO 范式被证明是一个很好的范式。学习它,理解它,爱它——你会很高兴你做到了:-)
(a) 我最初是作为一个玩笑写的,但结果证明它是正确的,因此并不那么好笑。单体苯乙烯恰好是由碳和氢 C8H8
制成的,而聚苯乙烯是由它们的基团 (C8H8)n
制成的。
也许我应该说息肉是字母 p
的多次出现,尽管现在我不得不解释这个笑话,即使这看起来也不好笑。
有时,您应该在落后时退出:-)
多态性是指您可以将对象视为某事物的通用版本,但是当您访问它时,代码会确定它是哪种确切类型并调用相关代码。
这是 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 类将该代码的执行委托给相关的子类。
这段代码被称为是多态的,因为执行的确切代码由运行时引用的子类决定。
我希望这对你有帮助。
Class_Excel
、Class_CSV
调用某种工厂类,或者调用 Reader
类。无论哪种方式,某种迭代的 if/then/else 都必须存储在某个地方。
来自 Understanding and Applying Polymorphism in PHP,感谢 Steve Guidetti。
多态性是一个非常简单的概念的长词。多态性描述了面向对象编程中的一种模式,其中类具有不同的功能,同时共享一个公共接口。多态性的美妙之处在于,使用不同类的代码不需要知道它使用的是哪个类,因为它们都以相同的方式使用。多态性的现实世界类比是按钮。每个人都知道如何使用按钮:您只需对其施加压力。然而,按钮的“作用”取决于它所连接的对象和使用它的上下文——但结果并不影响它的使用方式。如果你的老板让你按一个按钮,那么你已经掌握了执行任务所需的所有信息。在编程世界中,多态性用于使应用程序更加模块化和可扩展。您可以创建根据需要选择的可互换对象,而不是描述不同操作过程的凌乱的条件语句。这就是多态性的基本目标。
如果有人对这些人说 CUT
外科医生 发型师 演员
会发生什么?
外科医生将开始做一个切口。
发型师会开始剪别人的头发。
演员会突然停止在当前场景之外的表演,等待导演指导。
所以上面的表示显示了什么是 OOP 中的多态性(同名,不同的行为)。
如果你要去面试,面试官要求你在我们坐的同一个房间里讲述/展示一个多态性的活生生的例子,比如说 -
答案 - 门/窗
想知道如何?
通过门/窗——人可以进来,空气可以进来,光可以进来,雨可以进来,等等。
为了更好地理解它,我使用了上面的例子。如果您需要参考代码,请按照上面的答案。
.foo()
方法,那么它们应该共享一个公共接口。然而,这不是真的,并且会导致不正确的抽象。一个接口应该定义一个要播放的角色,它可能有许多不同的实现,但都从同一组输入中提取并从同一组输出中返回一些东西。外科医生、造型师或演员的 x.cut(...)
输入不同,输出也不同。
类推简单
美国总统使用多态性。如何?嗯,他有很多顾问:
军事顾问 法律顾问 核物理学家(作为顾问)等
每个人都应该只对一件事负责:示例:
总统不是锌涂层或量子物理学方面的专家。他不知道很多事情。但他确实知道如何治理国家。
代码有点类似:关注点和责任应该与相关的类/人分开。这使得维护代码更容易,尤其是在您进行更改时。变化是不可避免的。当事情发生变化时,您不想破坏应用程序的其他部分。总统应该坚持管理国家,而不是深入专业领域的本质:
为什么总统知道所有这些具体事情是个坏主意?
如果总统要具体告诉人们该做什么,那就意味着总统需要确切地知道该做什么。如果总统需要自己知道具体的事情,那就意味着当你需要做出改变时,你需要在两个地方做出改变,而不仅仅是一个地方。
例如,如果 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();
}
}
不!不!不!在上述情况下,总统正在做所有的工作:他知道增加部队人数和预先存在的条件。这意味着如果中东政策发生变化,那么总统将不得不改变他的命令,以及彼得雷乌斯阶级。我们应该只需要改变彼得雷乌斯类,因为总统不应该陷入那种细节。他不需要知道细节。他只需要知道,只要他下一个订单,一切都会得到处理。所有细节都应留给专家。
这使总统可以做他最擅长的事情:制定总体政策,看起来不错并打高尔夫球:P。
它是如何实际实现的——通过基类或通用接口
简而言之,这实际上是多态性。它究竟是如何完成的?通过“实现通用接口”或使用基类(继承) - 请参阅上面的答案,其中更清楚地详细说明了这一点。 (为了更清楚地理解这个概念,您需要知道什么是接口,并且您需要了解什么是继承。没有它,您可能会遇到困难。)
换句话说,Petraeus、Condi 和 HealthOfficials 都将是“实现接口”的类 - 我们称其为 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 :))
我真的希望它可以帮助你。如果您有任何不明白的地方发表评论,我会再试一次。
if healthAdvisor? then do this:
和 if petraus then do that etc.
这种模式需要重复,这是不必要且复杂的。见上面的编辑。
多态性是一种将对象类视为父类的能力。
例如,假设有一个名为 Animal 的类,以及一个继承自 Animal 的名为 Dog 的类。多态性是将任何 Dog 对象视为 Animal 对象的能力,如下所示:
Dog* dog = new Dog;
Animal* animal = dog;
classes have different functionality while sharing a common interface
多态性:
这是面向对象编程的概念。不同对象以自己的方式响应相同消息的能力称为多态性。
多态性源于每个类都存在于自己的命名空间中。在类定义中分配的名称不会与在它之外的任何地方分配的名称冲突。对象的数据结构中的实例变量和对象的方法都是如此:
正如 C 结构的字段位于受保护的命名空间中一样,对象的实例变量也是如此。
方法名称也受到保护。与 C 函数的名称不同,方法名称不是全局符号。一个类中的方法名不能与其他类中的方法名冲突;两个非常不同的类可以实现同名的方法。
方法名称是对象接口的一部分。当发送消息请求对象执行某项操作时,该消息会命名对象应执行的方法。因为不同的对象可以有同名的方法,所以必须相对于接收消息的特定对象来理解消息的含义。发送给两个不同对象的相同消息可以调用两种不同的方法。
多态的主要好处是它简化了编程接口。它允许建立可以在课堂上重复使用的约定。无需为添加到程序中的每个新功能发明一个新名称,而是可以重复使用相同的名称。编程接口可以描述为一组抽象行为,与实现它们的类完全不同。
例子:
示例 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
汽车.java
public class Car {
int price;
String name;
String color;
public void move(){
System.out.println("Basic Car move");
}
}
让我们实现福特汽车的例子。
Ford 扩展了 Car 类型以继承它的所有成员(属性和方法)。
福特.java
public class Ford extends Car{
public void move(){
System.out.println("Moving with V engine");
}
}
上面的 Ford 类扩展了 Car 类,还实现了 move() 方法。尽管移动方法已经通过继承提供给福特,但福特仍然以自己的方式实现了该方法。这称为方法覆盖。
本田.java
public class Honda extends Car{
public void move(){
System.out.println("Move with i-VTEC engine");
}
}
和福特一样,本田也扩展了 Car 类型,并以自己的方式实现了 move 方法。
方法覆盖是启用多态性的一个重要特性。使用方法覆盖,Sub 类型可以更改通过继承可用的方法的工作方式。
多态Example.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 类型引用。
请注意这里的重要一点,超类类型可以引用对象的子类类型,但反之亦然。原因是超类的所有成员都可用于子类使用继承,并且在编译期间,编译器会尝试评估我们正在使用的引用类型是否具有他试图访问的方法。
因此,对于 PolymorphismExample 中的引用 car、f 和 h,move 方法存在于 Car 类型中。因此,编译器通过编译过程没有任何问题。
但是当涉及到运行时执行时,虚拟机调用子类型对象上的方法。因此,方法 move() 是从它们各自的实现中调用的。
因此,所有对象都是 Car 类型,但在运行时,执行取决于发生调用的对象。这称为多态性。
通常这是指 A 类型的对象表现得像 B 类型的对象的能力。在面向对象的编程中,这通常是通过继承来实现的。一些维基百科链接阅读更多:
面向对象编程中的多态性
类型多态性
编辑:修复断开的链接。
classes have different functionality while sharing a common interface
多态是这样的:
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() 实例
我知道这是一个较老的问题,有很多很好的答案,但我想包括一个句子的答案:
将派生类型视为其基类型。
上面有很多例子表明了这一点,但我觉得这是一个很好的简洁答案。
(我正在浏览另一篇关于完全不同的文章.. 多态性突然出现......现在我以为我知道多态性是什么......但显然不是以这种美丽的方式解释......想把它写下来......更好的还是会分享它...)
http://www.eioba.com/a/1htn/how-i-explained-rest-to-my-wife
从这部分继续阅读:
.....多态性。这是一种怪异的说法,不同的名词可以使用相同的动词。
一般而言,它是一种使用相同或表面上相似的 API 连接多种不同类型对象的能力。有多种形式:
函数重载:定义多个同名、不同参数类型的函数,如sqrt(float)、sqrt(double)、sqrt(complex)。在大多数允许这样做的语言中,编译器会自动为传递给它的参数类型选择正确的类型,因此这是编译时多态性。
OOP 中的虚拟方法:一个类的方法可以根据其子类的具体情况定制各种实现;据说这些中的每一个都覆盖了基类中给出的实现。给定一个可能属于基类或其任何子类的对象,可以即时选择正确的实现,因此这是运行时多态性。
模板:一些 OO 语言的一个特性,函数、类等可以通过类型参数化。例如,您可以定义一个通用的“列表”模板类,然后将其实例化为“整数列表”、“字符串列表”,甚至可能是“字符串列表列表”等。通常,您为任意元素类型的数据结构编写一次代码,编译器就会为各种元素类型生成代码版本。
术语多态性来自:
聚 = 许多
态射=改变的能力
在编程中,多态性是一种“技术”,它可以让您“看待”一个对象不仅仅是一种类型的事物。例如:
一个学生对象也是一个人对象。如果您“看”(即投射)学生,您可能会要求提供学生证。你不能总是对一个人这样做,对吧? (一个人不一定是学生,因此可能没有学生证)。但是,一个人可能有一个名字。一个学生也是。
底线,从不同的“角度”“看”同一个物体可以给你不同的“视角”(即不同的属性或方法)
所以这种技术可以让你构建可以从不同角度“观察”的东西。
为什么我们使用多态性?对于初学者...抽象。此时应该有足够的信息:)
让我们打个比方。对于一个给定的音乐剧本,每个演奏它的音乐家都会在解释中给出自己的感受。
音乐家可以用接口抽象,音乐家所属的流派可以是一个抽象类,它定义了一些全局的解释规则,每个演奏的音乐家都可以用一个具体的类来建模。
如果您是音乐作品的听众,您会参考脚本,例如巴赫的“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());
}
AnnHalloway
和 VictorBorga
感觉它们应该是对象而不是类 - 您的示例使用 eg 会更好读。 public class Pianist implements Musician
和 victorBorge = new Pianist();
等。
我为另一个问题提供了多态性的高级概述:
希望能帮助到你。提取物...
...它有助于从一个简单的测试和[多态性]的定义开始。考虑代码:
Type1 x;
Type2 y;
f(x);
f(y);
在这里, f() 将执行一些操作,并被赋予值 x 和 y 作为输入。要成为多态,f() 必须能够对至少两种不同类型(例如 int 和 double)的值进行操作,找到并执行适合类型的代码。
(在 Polymorphism in c++ 继续)
在面向对象编程中,多态性是指编程语言根据对象的数据类型或类以不同方式处理对象的能力。更具体地说,它是为派生类重新定义方法的能力。
多态性是对象的一种能力,可以采取多种形式。例如,在人类阶级中,当我们谈论关系时,一个人可以采取多种形式。例:男人对儿子是父亲,对妻子是丈夫,对学生是老师。
多态性是对象具有多种形式的能力。 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");
}
}
结果是:
https://i.stack.imgur.com/ZWtxV.jpg
如需更多信息,请访问 https://github.com/m-vahidalizadeh/java_advanced/blob/master/src/files/PolymorphismExample.java。我希望它有所帮助。
多态性是程序员编写同名方法的能力,这些方法根据这些对象的需要为不同类型的对象做不同的事情。例如,如果您正在开发一个名为 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
其他一些答案似乎暗示多态性仅与继承结合使用。例如,可能 Fraction
和 ComplexNumber
都实现了一个名为 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()
方法,即使开发人员无法提前知道用户将选择分数还是复数。
多态性的字面意思是多种形状。 (或多种形式):来自不同类和同名方法的对象,但工作流程不同。一个简单的例子是:
考虑一个人 X。
他只是一个人,但他的行为却是一样多的。你可能会问如何:
他是他母亲的儿子。朋友对他的朋友。一个弟弟对他妹妹。
OOP中的多态性意味着一个类可以有不同的类型,继承是实现多态性的一种方式。
例如,Shape 是一个界面,它有 Square、Circle、Diamond 子类型。现在你有了一个 Square 对象,你可以自动将 Square 向上转换为 Shape,因为 Square 是一个 Shape。但是当你尝试将Shape向下转换为Square时,你必须进行显式类型转换,因为你不能说Shape是Square,它也可能是Circle。所以你需要用像Square s = (Square)shape
这样的代码手动投射它,如果形状是圆形,你会得到java.lang.ClassCastException
,因为圆形不是方形。
多态性:
根据类的实例不同执行,而不是引用变量的类型。
接口类型引用变量可以引用实现该接口的任何类实例。
什么是多态性?
多态性是以下能力:
在调用专用类型的方法而不是通用类型的方法时,只知道其通用类型,就可以对专用类型的实例调用操作:这是动态多态性。
定义几个具有保存名称但具有不同参数的方法:这是静态多态性。
第一个如果是历史定义,也是最重要的。
多态性是做什么用的?
它允许创建类层次结构的强类型一致性,并做一些神奇的事情,比如管理不同类型的对象列表,而不知道它们的类型,但只知道它们的父类型之一,以及数据绑定。
样本
这里有一些形状,比如点、线、矩形和圆形,它们的 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使用所谓的虚拟表来处理我们所操作的对象的真实类型。所以它调用 good 方法,这里调用 Shape.Draw() 如果 Shape 是 Point 调用 Point.Draw()。所以代码绘制形状。
更多阅读
Polymorphism in Java (Level 2)
Polymorphism (C# Programming Guide)
多态性是在给定类中使用对象的能力,其中构成对象的所有组件都由给定类的子类继承。这意味着一旦这个对象被一个类声明,它下面的所有子类(以及它们的子类,等等,直到你到达最远/最低的子类)都会继承该对象及其组件(构成)。
请记住,每个类都必须保存在单独的文件中。
以下代码举例说明了多态性:
超类:
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?");
}
}
执行方法,引用Parent类启动:
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 更远。这就是多态性的概念。这里还探讨了继承的概念,其中一个类可以使用或由子类进一步定义。
希望这会有所帮助并说明清楚。当我找到可以用来验证代码的计算机时,我会发布结果。谢谢你的耐心!
多态性允许相同的例程(函数、方法)作用于不同的类型。
由于许多现有的答案将子类型与多态性混为一谈,因此这里有三种方法(包括子类型)来实现多态性。
参数(通用)多态性允许例程接受一个或多个类型参数,除了普通参数,并在这些类型上运行自己。
子类型多态性允许例程对其参数的任何子类型进行操作。
Ad hoc 多态性通常使用例程重载来授予多态性行为,但也可以引用其他多态性实现。
也可以看看:
http://wiki.c2.com/?CategoryPolymorphism
https://en.wikipedia.org/wiki/Polymorphism_(computer_science)
在面向对象的语言中,多态允许通过相同的接口处理和处理不同的数据类型。例如,考虑 C++ 中的继承:B 类派生自 A 类。A* 类型的指针(指向 A 类的指针)可用于处理 A 类的对象和 B 类的对象。
编码术语中的多态性是指您的对象可以通过继承等方式作为多种类型存在。如果您创建一个名为“Shape”的类,它定义了您的对象具有的边数,那么您可以创建一个继承它的新类,例如“Square” ”。当您随后制作“Square”的实例时,您可以根据需要将其从“Shape”来回投射到“Square”。
多态性使您能够创建一个模块调用另一个模块,但编译时依赖点是针对控制流而不是控制流。
通过使用多态性,高级模块不依赖于低级模块。两者都依赖于抽象。这有助于我们应用依赖倒置原则(https://en.wikipedia.org/wiki/Dependency_inversion_principle)。
这是我找到上述定义的地方。在视频播放大约 50 分钟后,讲师解释了上述内容。 https://www.youtube.com/watch?v=TMuno5RZNeE
不定期副业成功案例分享
Poly = many and Morph = change or form