作者:劲吻2502877607 | 来源:互联网 | 2023-02-03 13:12
使用DuckTyping方法,下面是两个类Duck
&Person
,
class Duck:
def quack(self):
print('Quack')
def fly(self):
print('Flap')
class Person:
def quack(self):
print('I\'m quacking like a duck')
def walk(self):
print('Walk')
def quackFlap(creature):
try:
creature.quack()
except: # EAFP
print('Cannot quack')
try:
creature.flap() # Using hasattr() will violate EAFP
except: # EAFP
print('Cannot flap')
dOnald= Duck()
quackFlap(donald)
p = Person()
quackFlap(p) # Duck Typing approach says, Person is not Duck.
使用基于类的继承方法,以下是两个类Bird
&Duck
,
class Bird(object):
def quack(self):
print('Quack')
def fly(self):
print('Fly')
class Duck(Bird):
def quack(self):
print('I\'m quacking like a duck')
def fly(self):
print('Flap')
def quackFlap(creature):
if isinstance(creature, Bird):
creature.quack()
creature.flap()
b = Bird()
quackFlap(b)
d = Duck()
quackFlap(d) # Inheritance allowed isinstance() check - Error handling
题:
1)DuckTyping避免子类化吗?因为在子类化中,我们看不到DuckTyping方法的必要性
2)什么时候DuckTyping比基于类的继承更好?
1> Danilo M. Ol..:
1)DuckTyping避免子类化吗?因为在子类化中,我们不需要DuckTyping方法
一点也不。当您需要访问未在超类上定义的内容时,鸭子类型只会使不必要地对子类类型进行强制转换/检查。但是通过良好的设计和正确使用多态性,您可以避免这样做(使用instanceof + cast来访问子类的特殊性)。
2)什么时候DuckTyping比基于类的继承更好?
这确实取决于...当类之间没有“ IS A”关系时,应该避免继承,主要是在将其用作重新利用代码的手段时。如果存在“ IS A”关系,并且代码依赖于“ instanceof”的使用,则表明设计不良,即未正确使用多态。
鸭子类型化是一种便捷的方式,可以在不依赖于Java之类的抽象类/接口的情况下获得多态代码。但是抽象类/接口定义了契约。使用鸭类型,由于缺乏正式关系,您可以在代码中引入细微的错误。如果您的“庸医”根本不是“庸医”,那么您将有麻烦。对于继承,由于子类抽象类的契约性质,这种情况不太可能发生。
在静态类型语言中,将无法编译在基类上未定义的方法。因此,无需进行鸭嘴式操作,如果您需要调用基类中未定义的任何内容,则需要对子类进行强制类型转换,并使用instanceof运算符避免无效的强制类型转换引发错误。