4
\$\begingroup\$

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')
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Oct 31, 2016 at 14:34
\$\endgroup\$
0

2 Answers 2

5
\$\begingroup\$

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.

answered Oct 31, 2016 at 19:09
\$\endgroup\$
2
  • \$\begingroup\$ You made my night ! Nice answer. One small thing: I'd just go with str.format() instead of %. \$\endgroup\$ Commented 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\$ Commented Oct 31, 2016 at 21:06
2
\$\begingroup\$

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'
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
answered Oct 31, 2016 at 19:35
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.