|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
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.
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?
@
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
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)
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!
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.
(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.