我刚刚读了卢卡·卡德利的一篇文章,他解释了多态性的类型:
这篇文章名为理解类型、数据抽象与多态性。
Cardelli在本文中定义了几种类型的多态性:
我还发现一些理论认为只有两种类型的多态性是宽泛的:
所以我有点困惑。我正在用Python学习OOP,当我读到python是动态类型语言时,所以我请求python专家解释在python中使用哪种类型的多态性?
发布于 2016-11-09 18:31:53
正如您所发现的,多态有许多不同的定义。这个答案将从实际的角度来讨论,可能与学术定义不一致。
我相信,这是大多数人对多态这个词的看法。这是子类继承方法的地方,然后可以重写.例如(Python2.7):
class Foo(object):
def test(self):
print self.name()
def name(self):
return "Foo"
class Bar(Foo):
def name(self):
return "Bar"
foo = Foo()
bar = Bar()
print type(foo)
print type(bar)
print isinstance(bar, type(foo))
Foo().test()
Bar().test()输出:
<class '__main__.Foo'>
<class '__main__.Bar'>
True
Foo
Bar这只适用于Java或C#中的子类型多态性。
Python还有一个叫做鸭子类型的特性。从技术上讲,这也是子类型继承--如果你区分子类型和继承(我认为这是思考Python的正确方法)--这个术语来自一句俗语:“如果它看起来像鸭子,那么它很可能是鸭子”,它通常被缩写为“如果它像鸭子一样叫.”我认为这在学术文献中是否是多态并不重要,因为它可以用来解决同样的问题:
class Foo(object):
def test(self):
print "Foo"
class Bar(object):
def test(self):
print "Bar"
foo = Foo()
bar = Bar()
print type(foo)
print type(bar)
print isinstance(bar, type(foo))
Foo().test()
Bar().test()输出:
<class '__main__.Foo'>
<class '__main__.Bar'>
False
Foo
Bar正如您所看到的,我们可以得到和以前一样的行为,但是现在Bar不是一个Foo。鸭子类型在Python程序中非常常用,而其子类型不是。例如,创建类似列表的对象是很常见的,其中list的所有(实际上:大多数)操作都实现了,并且它被传递到方法中,就好像它是list一样--尽管从纯类型的角度来看,它实际上不是从list派生的类型。
我认为这意味着类似于Java或C#中的泛型。我不认为这与Python相关,但我没有跟上Python 3的速度。
这是个有趣的案子。从纯Python的角度来看,这是没有意义的,因为您不能重载方法。也就是说,您不能两次定义同一个方法名。有趣的是,在Jython (编译为在JVM上运行的Python )中,您获得了Java和Python都没有的特性:双分派。在确定从python语句调用重载Java方法的哪个版本时,运行时将查看调用参数的实际类型,并动态地选择版本。在Java中,重载的方法被绑定到编译时调用,这在技术上是多态的,但实际上并不有趣。双调度重载实际上可以用来实现一些有趣的效果。我希望这在IronPython中也能类似地工作,并调用C#库。
我想我已经覆盖了这里的大部分基地。欢迎对可能被视为多态特性的其他特性进行评论。我不确定的一件事是使用__getattr__或__setattr__等创建合成或虚拟属性/方法的能力。此外,我认为您可以提出这样的论点,即传递方法引用是多态的类型,但这可能有点过于夸张了。
https://softwareengineering.stackexchange.com/questions/335704
复制相似问题