繁体   English   中英

为什么要从继承的类调用基类构造函数

[英]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.stringBase之上self.number

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM