我正在尝试理解 Python 继承,下面是从类Car
继承的类CarWithBrakes
:
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())
运行此代码将产生:
{'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):
轮子属性不应该作为CarWithBrakes
从Car
继承而可用吗?
这里有两个问题。
CarWithBrakes
确实会覆盖Car
的__init__
方法。在重写的方法中,未设置wheels
属性。通常,您将要与子类共享的工作(例如设置wheels
属性)委派给子类初始值设定项super().__init__(...)
。
其次,您不必要地混合了继承和聚合。CarWithBrakes
是继承的汽车,没有理由传递一个Car
实例来保留CarWithBrakes.__init__
。
在 Python 中,如果您希望为派生类型执行基构造函数,则必须调用该构造函数。可以使用允许您访问基类型的super()
执行此操作。
因此,您的CarWithBrakes
应如下所示:
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
您也不想传入car
实例,而是直接创建CarWithBrakes
。带刹车的汽车是一辆汽车;但一辆带刹车的汽车不包含另一辆汽车。