Reputation: 163
I'm attempting to understand Python inheritence and below class CarWithBrakes
inherits from class Car
:
class Car :
def __init__(self , wheels):
self.wheels = wheels
self.jsonTransform = {}
self.jsonTransform['wheels'] = wheels
def toJson(self):
return self.jsonTransform
def get_wheels(self):
return self.wheels
class CarWithBrakes(Car):
def __init__(self , car, brakes):
self.car = car
self.brakes = brakes
def toJson(self):
self.jsonTransform = {}
self.jsonTransform['wheels'] = self.car.wheels
self.jsonTransform['brakes'] = self.brakes
return self.jsonTransform
c = Car("wheels")
print(c.toJson())
b = CarWithBrakes(c , "brakes")
print(b.toJson())
print(b.get_wheels())
Running this code produces:
{'wheels': 'wheels'}
{'wheels': 'wheels', 'brakes': 'brakes'}
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-62-9b4b5598414b> in <module>
30 b = CarWithBrakes(c , "brakes")
31 print(b.toJson())
---> 32 print(b.get_wheels())
<ipython-input-62-9b4b5598414b> in get_wheels(self)
11
12 def get_wheels(self):
---> 13 return self.wheels
14
15 class CarWithBrakes(Car):
Shouldn't wheels attribute be available as CarWithBrakes
inherits from Car
?
Upvotes: 4
Views: 50
Reputation: 387547
In Python, you will have to call the base constructor if you want that to execute for your derived type. You can do this using super()
which allows you to access the base type.
So your CarWithBrakes
should look like this:
class CarWithBrakes(Car):
def __init__(self, wheels, brakes):
# call base implementation
super().__init__(wheels)
# no need to set `self.wheels` since that is done in the base
# but do set the `brakes` which the base class does not know about
self.brakes = brakes
You also don’t want to pass in a car
instance but instead create a CarWithBrakes
directly. A CarWithBrakes is a Car; but a CarWithBrakes does not contain another Car.
Upvotes: 2
Reputation: 78650
There are two issues here.
CarWithBrakes
does override the __init__
method of Car
. In the overridden method, the wheels
attribute is not set. Usually, you delegate work you want to share with the child class (such as setting the wheels
attribute) to the child class initializer via super().__init__(...)
.
Second, you are unnecessarily mixing inheritance and aggregation. A CarWithBrakes
is-a car by inheritance, there's no reason to pass a Car
instance to hold onto in CarWithBrakes.__init__
.
Upvotes: 4