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


当前回答

多态:

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

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

其他回答

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

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的多次出现,尽管现在我必须解释这个笑话,即使这似乎也不好笑。

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

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

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

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

多态性是程序员编写同名方法的能力,这些方法根据对象的需要,为不同类型的对象做不同的事情。例如,如果您正在开发一个名为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)中,多态性允许开发人员调用方法,而不必事先知道对象的类型,并相信将调用方法的正确实现。例如,假设用户选择创建的数字类型:

$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()实例