I'm trying to do some basic inheritance between the 3 classes and use some simple methods, and I'm looking to learn what should be the correct structure between them and what can be improved.
class Animal:
def __init__(self, kind, place):
self.kind = kind
self.place = place
#This class inherits kind and place arguments from Animal class (which can work for any animal)
#Initiates a Dog object with name, gender and breed parameters.
class Dog(Animal):
def __init__(self, name, gender, breed):
self.name = name
self.gender = gender
self.breed = breed
Animal.__init__(self, 'Dog', 'Ground')
#woof method, just prints an action for the Dog object with his name.
def woof(self, *args):
print("%s just did a %s woof" % (self.name, *args))
#getallinfo method, get's all the parametrs of both classes.
def getallinfo(self):
print("%s is a %s %s %s, sitting on the %s" % (self.name, self.gender, self.breed, self.kind, self.place))
#Cat class inherits the paramets of use for a Cat (similar things) like name, gender and breed, which they both share, also the getallinfo method and initiate them.
class Cat(Dog):
def __init__(self, name, gender, breed):
Dog.__init__(self, name, gender, breed)
Animal.__init__(self, 'Cat', 'Ground')
#Speak method, returns a print for a cat "meow" with him name.
def speak(self, *args):
print("%s just did a %s meow" % (self.name, *args))
#Here I create 3 objects, 2 dogs and 1 cat with selected arguments.
#And check for some methods on the objects.
Mickey = Dog('Mickey', 'Male', 'Bulldog')
Flora = Dog('Flora','Female','Pug')
Tina = Cat('Tina','Female','Persian')
Tina.getallinfo()
Tina.speak('soft')
Dog.getallinfo(Flora)
Dog.woof(Mickey, 'loud')
2 Answers 2
Inheritance is typically describe as an "is-a" relationship. So when you derive a Dog
from an Animal
, we can say that a Dog
is a Animal
. However, when you derive a Cat
from a Dog
, unless this is some other planet, we can't correctly say that a Cat
is a Dog
. Further, we can, without error, invoke Tina.woof('ferocious')
to cause "Tina just did a ferocious woof". Since no Persian cat I've ever seen has been known to "woof" either ferociously or not, this is an alarming and surprising result.
Better would be to derive both Dog
and Cat
types from Animal
. If you have other animals which don't have names, breeds or genders, you could have some intermediate class such as Pet
that would capture the additional detail not already in Animal
. Otherwise, just add those attributes to Animal
.
Finally, we can put the speak
method in the base Animal
class. One simple illustration is this:
class Animal:
def __init__(self, kind, place):
self.kind = kind
self.place = place
def speak(self, adverb):
print("%s just did a %s %s" % (self.name, adverb, self.speechtype))
#getallinfo method, get's all the parametrs of both classes.
def getallinfo(self):
print("%s is a %s %s %s, sitting on the %s" % (self.name, self.gender, self.breed, self.kind, self.place))
#This class inherits kind and place arguments from Animal class (which can work for any animal)
#Initiates a Dog object with name, gender and breed parameters.
class Dog(Animal):
def __init__(self, name, gender, breed):
self.name = name
self.gender = gender
self.breed = breed
self.speechtype = "woof";
Animal.__init__(self, 'Dog', 'Ground')
#Cat class inherits the paramets of use for a Cat (similar things) like name, gender and breed, which they both share, also the getallinfo method and initiate them.
class Cat(Animal):
def __init__(self, name, gender, breed):
self.name = name
self.gender = gender
self.breed = breed
self.speechtype = "meow";
Animal.__init__(self, 'Cat', 'Ground')
#Here I create 3 objects, 2 dogs and 1 cat with selected arguments.
#And check for some methods on the objects.
Mickey = Dog('Mickey', 'Male', 'Bulldog')
Flora = Dog('Flora','Female','Pug')
Tina = Cat('Tina','Female','Persian')
Tina.getallinfo()
Tina.speak('soft')
Flora.getallinfo()
Mickey.speak('loud')
There's more that could be improved, but I hope that helps until others weigh in on your question and give more expansive answers.
-
\$\begingroup\$ You made my night ! Nice answer. One small thing: I'd just go with
str.format()
instead of%
. \$\endgroup\$Grajdeanu Alex– Grajdeanu Alex2016年10月31日 21:02:24 +00:00Commented Oct 31, 2016 at 21:02 -
\$\begingroup\$ @Dex'ter: absolutely agreed on the use of
str.format()
! I lacked the time to do a more comprehensive review, but may edit later. \$\endgroup\$Edward– Edward2016年10月31日 21:06:33 +00:00Commented Oct 31, 2016 at 21:06
The biggest issue in your code was inheriting Cat
from Dog
, and it doesn't make any sense. Dog
and Cat
classes should be instances from the Animal
class, which can inherit every attributes in Animal
.
So first, I defined all the attributes in the Animal
class. Note that the kind of animal (self.kind
) was defined by the name of the instance (self.__class__.__name__
), either "Dog", "Cat", or any other name of species when used for inheritance. There are two variables with default value empty ("palce" and "action"), those are further assigned individually based on different instance ("dog" is on the "ground" and "dog" will "woof").
class Animal:
place = ''
action = ''
def __init__(self, name, gender, breed):
self.kind = self.__class__.__name__
self.name = name
self.gender = gender
self.breed = breed
def speak(self, sound):
self.sound = sound
print("{} just did a {} {}".format(self.name, self.sound, self.action))
def getallinfo(self):
print("{} is a {} {} {}, sitting on the {}".format(self.name, self.gender, self.breed, self.kind, self.place))
#This class inherits kind and place arguments from Animal class (which can work for any animal)
#Initiates a Dog object with name, gender and breed parameters.
class Dog(Animal):
place = 'Ground'
action = 'woof'
#Cat class inherits the paramets of use for a Cat (similar things) like name, gender and breed, which they both share, also the getallinfo method and initiate them.
class Cat(Animal):
place = 'Ground'
action = 'meow'
#Here I create 3 objects, 2 dogs and 1 cat with selected arguments.
#And check for some methods on the objects.
Mickey = Dog('Mickey', 'Male', 'Bulldog')
Flora = Dog('Flora','Female','Pug')
Tina = Cat('Tina','Female','Persian')
Tina.getallinfo()
Tina.speak('soft')
Flora.getallinfo()
Mickey.speak('loud')
This is actually very straightforward, so next time when you need to add another instance to the Animal
class, just add the following lines for example and it will do.
class Cow(Animal):
place = 'Ground'
action = 'moo'
Explore related questions
See similar questions with these tags.