简体   繁体   中英

Duck typing Vs class based Inheritance

Using DuckTyping approach, below are two classes 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.

Using class based inheritance approach, below are two classes 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

Question:

1) Does DuckTyping avoid Subclassing? because on subclassing, we do not see the necessity of DuckTyping approach

2) When DuckTyping is better than class based inheritance?

1) Does DuckTyping avoid Subclassing? because on subclassing, we do not the necessity of DuckTyping approach

Not at all. Duck typing only turns unnecessary doing casts/checkings to the subclass type when you need to access something that is not defined on the superclass. But with a good design and a proper use of polymorphism you avoid doing this (using instanceof + cast to access the particularity of a subclass).

2) When DuckTyping is better than class based inheritance?

It really depends... Inheritance should be avoided when there is no "IS A" relationship between the classes, mainly when it's used just as a mean to re-utilize code. When there is an "IS A" relationship, and the code relies on the use of "instanceof", it's a sign of a bad design, ie, that polymorphism isn't being properly used.

Duck typing is a handy way to have a polymorphic code without relying on abstract classes/interfaces like Java, for instance. But an abstract class/interface defines a contract. With duck typing you can introduce subtle bugs in your code due this lack of formal relationship. If your "quack" isn't a "quack" at all, you'll be in trouble. With inheritance, this is less likely to happen due the contractual nature of subclassing abstract classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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