【发布时间】:2011-10-15 02:08:22
【问题描述】:
这是this question的后续跟进:
Effective Java 第 2 版,第 17 条:设计和记录继承,否则禁止:
为了允许继承,类必须遵守更多的限制。构造函数不得直接或间接调用可覆盖的方法。如果您违反此规则,将导致程序失败。超类构造函数在子类构造函数之前运行,因此子类中的覆盖方法将在子类构造函数运行之前被调用。如果覆盖方法依赖于子类构造函数执行的任何初始化,则该方法将不会按预期运行。
由于我们只涉及 Java 构造函数的初始化方面,我认为在这个问题中将 Java 的构造函数与 Python 的 __init__() 进行比较是安全的。
我猜是因为在Python 中,我可以灵活地决定何时调用(在这种情况下初始化我当前类的数据属性之后)我祖先的__init__(),而Java 中super() 需要是构造函数调用中的第一条语句,我可以安全地从 __init__() 调用覆盖的方法?
如果我对上述的猜测是正确的,作为一个祖先类的设计师,我会不会任由我的子类设计师摆布?如果子类设计者在初始化他的数据属性之前调用了我的__init__(),而我调用了该方法,我会导致程序失败!
【问题讨论】:
-
是的,你可以。而且我认为由子类编码器来确保他的子类以正确的顺序初始化事物。
-
我认为这是可持续软件设计的一个重要概念——如果你只记得不要从构造函数中调用可覆盖方法的规则,它将在未来为你节省大量时间。如果你违反了规则,一切都可能完美无缺,你只需要花更多的时间来确保它确实如此。在很多极端情况下,违反此规则是个好主意™。
-
“我认为在这个问题中将 Java 的构造函数与 Python 的 init 进行比较是安全的。”不好的假设。它们是不同的语言。具有不同的语义。
标签: python inheritance constructor