[英]Why call a base class constructor from inherited class
我一直在尝试理解这种用例,在这种情况下,我们经常从继承的类中调用基类构造函数,这样做的唯一目的是仅确保基类已初始化? 还是会有其他可能的用例?
class Base:
def __init__(self):
print('Base.__init__')
class A(Base):
def __init__(self):
super().__init__()
print('A.__init__')
这样做的唯一目的是仅确保初始化基类?
嗯,是的,但你是什么意思, 公正 ?
假设您的基类有一个存在的理由,那么它必须做一些事情。
除非它只是@staticmethod
函数的便捷集合, @staticmethod
它所做的任何事情都可能取决于其__init__
调用,因为这就是类对象的工作方式。
即使您的基类今天有一个空的__init__
,也可以调用它,以防将来发生更改。
还是会有其他可能的用例?
用例是确保对象的基类部分已正确初始化。 否则,您将无法安全地调用其任何非静态方法。
原则上,您的基类可以在其__init__
做一些棘手的事情(启动后台线程,或使用单例注册实例,或执行其他操作)。 因此,是的,除了分配实例变量之外,还可能有其他效果,但这仍然是初始化该基类的对象的一部分。
在C ++或Java中,编译器将要求您调用基类构造函数(通过自动插入零参数调用或给您错误)。
Python要求您自行调用它, 因为它是这样写的 :
如果基类具有
__init__()
方法,则派生类的__init__()
方法(如果有)必须显式调用它,以确保实例的基类部分的正确初始化。
之所以是面向对象设计的原理。 的A
“是一个” Base
,其中也可以等效地写成A
“具有-A” Base
。 除非您特别想干扰Base
的实现,否则必须允许按设计初始化该对象。 跳过构造函数将使Base
对象的初始化不正确,这会使任何希望其表现为Base
对象应有的行为的人感到失望。
当重写除构造函数以外的方法时,程序员可以自行决定委托给基类实现还是完全重写它。 这仍然可能导致错误的行为---我可以想到几个API文档,其中的各种方法都带有“如果重写此方法,则应调用super”作为胡椒文档。
这样做的目的是初始化基类通常初始化的所有东西。 例如,
class Base:
def __init__(self, number):
print('Base.__init__')
self.number = number
class A(Base):
def __init__(self, number, string):
super().__init__(number)
self.string = string
print('A.__init__')
在此代码示例中,它更加明显。 当A
调用基本构造函数时,基本构造函数将初始化所有需要的东西,例如self.number
。 这样, A
的其余初始化函数可以在基本初始化函数的基础上构建,而无需重新键入。 在此示例中, A
通过在self.string
之上添加self.string
在Base
之上self.number
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.