class Character(Entity):
def __init__(self, x, y, hp):
Entity.__init__(self, x, y)
self.hp = hp
self.items = []
Character
is a child class of the parent class Entity
. Entity
class also has a __init__
function. Why is there a need to write both the __init__
functions? Why not only write the __init__()
for the Character
class, which would overwrite the __init__()
for Entity
?
It depends what happens in Entity.__init__
! If (and only if) all it does is set self.x
and self.y
, you could do:
class Character(Entity):
def __init__(self, x, y, hp):
self.x = x
self.y = y
self.hp = hp
self.items = []
But this is one line longer already, and if anything else other than setting arguments to instance attributes gets done in Entity.__init__
(like, for example, self.items = []
in Character.__init__
) your Character
may not work properly.
It is good practice to call the super-class's __init__
method, to make sure that everything that needs to be done gets done.
You can make your code more general using super
:
class Character(Entity):
def __init__(self, x, y, hp):
super(Character, self).__init__(x, y)
So that if you change what Character
inherits from your __init__
still works.
You can do that but then you won't be calling the constructor of the superclass (Entity
). In that case it's up to your constructor to make sure the object ends up in a consistent state.
The alternative is to call the constructor of the superclass and then perform some further actions that are needed for a Character
instance. This means you'll already have an object in a consistent state (after the Entity
constructor is finished) and you're only making further adjustments that are specific to Character
objects.
Why is there a need to write both the __init__
functions?
There isn’t. You’re doing two completely different things here:
- You define
Character.__init__
, and
- You call
Entity.__init__
.
As you’ve noticed yourself, Character
’s __init__
method overrides Entity
’s. So if you want to invoke that, you need to call it explicitly from within Character
’s now.
That depends on what the classes are supposed to do.
If we suppose that the classes initiate their own stuff respectively, then you see that
Entity
inits its own attributes x
and y
and
Character
inits its additional attributes hp
and items
.
You could put the initialization of x
and y
to Character
as well, but then what about Entity
itself and tis other child classes?
Without adding to what is already said above - it is a common mistake to call __init__ method a constructor - but it is not!
Constructor is a __new__ method, and is seldom used.
Python documentation is a little bit cryptic on the issue - see here, but it never calls it constructor directly. Why? Constructor - in the standard OOP terminology, creates class instance - object - and returns it. __init__ simply does not do it!