繁体   English   中英

鸭子键入与基于类的继承

[英]Duck typing Vs class based Inheritance

使用DuckTyping方法,下面是DuckPerson两个类,

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.

使用基于类的继承方法,以下是BirdDuck两个类,

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)DuckTyping避免子类化吗? 因为在子类化中,我们不需要DuckTyping方法

一点也不。 当您需要访问超类中未定义的内容时,鸭子类型只会使不必要的转换/检查子类类型。 但是通过良好的设计和正确使用多态性,您可以避免这样做(使用instanceof + cast来访问子类的特殊性)。

2)什么时候DuckTyping比基于类的继承更好?

这确实取决于...当类之间没有“ IS A”关系时,应该避免继承,主要是在将其用作重新利用代码的手段时。 如果存在“ IS A”关系,并且代码依赖于“ instanceof”的使用,则表明设计不良,即未正确使用多态性。

鸭子类型化是一种便捷的方式,可以在不依赖于Java之类的抽象类/接口的情况下获得多态代码。 但是抽象类/接口定义了契约。 使用鸭类型,由于缺乏正式关系,您可以在代码中引入细微的错误。 如果您的“庸医”根本不是“庸医”,那么您将有麻烦。 对于继承,由于子类抽象类的契约性质,这种情况不太可能发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM