【问题标题】:Overloading only one specific attribute of __init__仅重载 __init__ 的一个特定属性
【发布时间】:2019-02-16 17:06:49
【问题描述】:

我有一个关于继承/重载的问题。要理解我的问题,我觉得最好先展示一段代码:

class A():
    def __init__(self):
        self.var1 = 10
        self.var2 = 20
        self.var3 = 30

class B(A):
    def __init__(self): #Bad, because I am probably overloading the whole "constructor"
        self.var2 = 15

B 类继承自 A 类。现在我的问题是,有没有办法只重载 B 类中属性 self.var2 的值,同时保持 self.var1 和 self.var3 原样?

【问题讨论】:

  • 先使用super
  • 先调用基类的init。使用 super() 或直接作为 A.__init__。很可能是重复的。
  • 虽然看起来很枯燥,但学习术语很有用:这称为覆盖,而不是重载。重载是另一回事。

标签: python inheritance overloading init


【解决方案1】:

如果您在A 中没有任何奇怪之处,例如只读属性,您可以简单地允许A.__init__ 完成它的工作,然后在B.__init__ 中更改您想要的一个值:

class B(A):
    def __init__(self):
        super().__init__()
        self.var2 = 15

但这会给设计带来一些可能的问题。如果 A 旨在可扩展,则可能值得考虑使用参数的默认值,而不是将它们硬编码到构造函数中:

class A():
    def __init__(self, var1=10, var2=20, var3=30):
        self.var1 = var1
        self.var2 = var2
        self.var3 = var3

现在子类可以调用他们的 super 初始化器并只覆盖他们需要的值:

class B(A):
    def __init__(self):
        super().__init__(var2=15)

或者更好

class B(A):
    def __init__(self, var2=15):
        super().__init__(var2=var2)

【讨论】:

    【解决方案2】:

    我认为您在概念上误解了 OOP 范式。首先,初始化程序仅用于初始化类的对象,但是在您的代码中__init__ 具有属性的硬编码值,因此类的每个对象都将具有这些属性的相同值。

    如果这是你想要的,那么将它们作为类变量或者只是将属性b 作为类属性。

    其次,在您的类B 中,虽然您是从类A 继承的,但初始化程序没有被重载,因为您没有显式调用super 类的__init__。所以要么在B类中使用super().__init__(),要么干脆将其删除,然后它会自动调用超类的__init__

    希望它能让事情更清楚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多