【问题标题】:Is it safe to call an overridden method from __init__()?从 __init__() 调用被覆盖的方法是否安全?
【发布时间】: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


【解决方案1】:

我可以安全地从__init__() 调用被覆盖的方法?

你是。在评估 __init__() 之前,self 绑定已经发生。

祖先类设计器任由我的子类设计器摆布?

这是普遍正确的,与__init__() 或其他任何事情无关。

子类开发人员可以做任何事情。另外,这是 Python:他们有你的源代码,也可以修改它。

如果子类设计者在初始化他的数据属性之前调用了我的__init__(),而我调用了那个方法,我会导致程序失败!

正确。发生这种情况的方式是子类设计器选择了一个您已经使用的名称。他们保证该计划会因他们选择的名称而失败。

【讨论】:

    猜你喜欢
    • 2011-12-13
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    相关资源
    最近更新 更多