簡體   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