Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Inheritance
#1
|Hello,

Below is the example code from the tutorial that I'm using to learn python
class Animal:
    def __init__(self):
        print("Animal created")

    def whoAmI(self):
        print("Animal")

    def eat(self):
        print("Eating")


class Dog(Animal):
    def __init__(self):
        Animal.__init__(self)
        print("Dog created")

    def whoAmI(self):
        print("Dog")

    def bark(self):
        print("Woof!")
I think I understand the concept of inheritance. but what confuses me is the use of Animal in Dog class

Animal.__init__(self)
Why here Animal used instead of self??
Is it to call the __init__ method of Dog class??
So if I want to use any method from say eat method from Animal class inside the bark method of derived the class, should I use Animal.eat(self). I tried self.eat(Self) but didn't work. ALso what is self inside the method call means in inheriatance

When to use self and base classes name when calling methods??


Then if there is a Class object attribute in Animal class say name = "Athul", and if want to access the name in derived class, should I use self.name or Animal.name??
How can I know which one to use??
What about in case of an attribute??

Thanks
Reply
#2
Animal.__init__ explicitly calls the __init__ method defined for Animal on line 2. Animal refers to the class, and gets the __init__ out of that class. Since Dog has it's own __init__, the __init__ from Animal won't be run otherwise. self is passed to Animal.__init__ because Animal.__init__ is an unbound method. That is, it's not associated with a particular instance of either class.

Dog does not have it's own eat, so you can use just self.eat() to call the eat method it inherits from Animal. But if you are calling self.eat, that method is bound to whatever instance you are currently dealing with. So you don't need to pass self to it as a parameter. That gets done automatically.

When you use self.method, you are calling a method bound to a particular instance of the class. When you use Class.method, you are calling a version of the method that is not bound to any instance of the class.

Class attributes (defined at the same level as methods, without self) are also inherited. You can use self.attribute or Class.attribute to get to them. Instance attributes (defined with self) are always going to depend on the instance, and should always be obtained with self.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
When you define a method in a subclass which has the same name as the superclass, you replace that method in the subclass. So in this case you'd lose the print("Animal created") behavior by overriding the __init__ method. Explicitly calling the superclass __init__ method by that name retains the behavior, so that you have both behaviors. Normally, we use super() for that instead; this is useful in examples where the superclass changes, or there are other more complex situations.. What tutorial are you using, and what Python version?
Reply
#4
@ichabod801

SO if I wan to call eat method inside bark method, I can use following

class Animal:

    hello = 23
    def __init__(self):
        print("Animal created")
 
    def whoAmI(self):
        print("Animal")
 
    def eat(self):
        print("Eating")
 
 
class Dog(Animal):
    def __init__(self):
        Animal.__init__(self)
        print("Dog created")
 
    def whoAmI(self):
        print("Dog")
 
    def bark(self):
        self.eat()
        print(Animal.hello)
        print("Woof!")


my_dog = Dog()
my_dog.bark()
but if I use Animal.eat(), i would have to pass in self as argument, since it is an unbound method(i did some google search to find this out)

class Animal:

    hello = 23
    def __init__(self):
        print("Animal created")
 
    def whoAmI(self):
        print("Animal")
 
    def eat(self):
        print("Eating")
 
 
class Dog(Animal):
    def __init__(self):
        Animal.__init__(self)
        print("Dog created")
 
    def whoAmI(self):
        print("Dog")
 
    def bark(self):
        Animal.eat(self)
        print(Animal.hello)
        print("Woof!")


my_dog = Dog()
my_dog.bark()
I'm still little bit confused about bounded method and unbounded method

@micseydel , I'm following one of the udemy complete python bootcamp, python version is 3.6.5
Reply
#5
I was just reading this thread to answer it and a question raised in my mind(learning python as well) that,

we can call eat() like this
Animal().eat()
but why we can't call eat() like this
Animal.eat()
why do we need to pass self
Animal.eat(self)
Reply
#6
Can just use self.eat() insted of Animal.eat(self).

There is super() which is more modern an better way.
class Animal:
    hello = 23
    def __init__(self):
        print("Animal created")

    def whoAmI(self):
        print("Animal")

    def eat(self):
        print("Eating")

class Dog(Animal):
    def __init__(self):
        super().__init__()
        print("Dog created")

    def whoAmI(self):
        print("Dog")

    def bark(self):
        super().eat()
        print(Animal.hello)
        print("Woof!")

my_dog = Dog()
my_dog.bark()
Output:
Animal created Dog created Eating 23 Woof!
Here super() used both for __init__ and method Inheritance.
So my_dog object has inherited eat() from __init__ then you want to also call eat() in method bark.
>>> # __init__
>>> my_dog.eat()
Eating

>>> # super call of method eat() in parent class
>>> my_dog.bark()
Eating  # super
23
Woof!
Reply
#7
The key point is that self is the instance. So you create the Animal class with an eat method. Animal.eat is unbound, because there is no instance. Since there is no instance, there is no self to automatically create. That's why you have to pass something to the self parameter. If you then create an instance (my_dog = Animal()). You now have an instance, and the method is bound to that instance. Now you can call my_dog.eat() and self (the instance my_dog) is automatically passed as the first parameter. Animal().eat() work because Animal() creates an instance (just one that is not referenced by a variable name). That instance is then automatically passed as self to the eat method call.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#8
(Aug-11-2018, 12:47 PM)ichabod801 Wrote: The key point is that self is the instance. So you create the Animal class with an eat method. Animal.eat is unbound, because there is no instance. Since there is no instance, there is no self to automatically create. That's why you have to pass something to the self parameter. If you then create an instance (my_dog = Animal()). You now have an instance, and the method is bound to that instance. Now you can call my_dog.eat() and self (the instance my_dog) is automatically passed as the first parameter. Animal().eat() work because Animal() creates an instance (just one that is not referenced by a variable name). That instance is then automatically passed as self to the eat method call.

Thanks ichabod801 for your help.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020