在__init__()中调用重写的方法安全吗?
这是对这个问题的后续讨论:
《Effective Java》第2版,第17条:为继承设计和文档,或者禁止继承:
为了允许继承,一个类必须遵守一些额外的限制。构造函数不能直接或间接调用可以被重写的方法。如果违反这个规则,程序就会出错。父类的构造函数在子类的构造函数之前运行,所以子类中的重写方法会在子类构造函数运行之前被调用。如果重写的方法依赖于子类构造函数完成的任何初始化,那么这个方法就不会按预期工作。
因为我们只讨论Java构造函数的初始化部分,我认为可以安全地将Java的构造函数与Python的__init__()
进行比较。
我猜测,在Python
中,我可以灵活决定何时调用(在这种情况下是初始化我当前类的数据属性之后)我的父类的__init__()
,而在Java中,super()
必须是构造函数调用中的第一条语句,所以我可能可以安全地在__init__()
中调用重写的方法?
如果我对上述猜测是正确的,那么作为父类设计者,我不就得听从子类设计者的安排吗?如果子类设计者在初始化他的数据属性之前调用了我的__init__()
,而这些数据属性会被他重写的方法使用,那么我调用那个方法时,就会导致程序出错!
1 个回答
我可以放心地在
__init__()
方法中调用被重写的方法吗?
可以的。在 __init__()
方法执行之前,self
已经绑定好了,也就是说对象已经创建好了。
祖先类的设计者会被我的子类设计者摆布吗?
这是普遍适用的,跟 __init__()
或其他任何东西都没有关系。
子类的开发者可以做任何事情。而且,这里是 Python:他们可以看到你的源代码,还可以修改它。
如果子类的设计者在初始化他的数据属性之前调用了我的
__init__()
,而这些数据属性会被他重写的方法使用,那么当我调用那个方法时,程序就会出错!
没错。这个问题的出现是因为子类设计者选择了一个你已经在使用的名字。通过这个名字的选择,他们确保了程序会出错。