Python 3:当子构造函数的参数多于父构造函数时,从继承的方法返回新的子类实例

Posted

技术标签:

【中文标题】Python 3:当子构造函数的参数多于父构造函数时,从继承的方法返回新的子类实例【英文标题】:Python 3: Returning a new child class instance from an inherited method, when child constructor has more arguments than parent constructor 【发布时间】:2017-12-06 19:30:01 【问题描述】:

假设我有一个父类和多个子类,它们通过包含有关它们所代表的想法的更具体信息来扩展父类。例如:

class Shape:
    def __init__(self, center):
        self.center = center


class Square(Shape):
    def __init__(self, center, side_length):
        super().__init__(self, center)
        self.side_length = side_length
        self.area = side_length ** 2


class Circle(Shape):
    def __init__(self, center, radius):
        super().__init__(self, center)
        self.radius = radius
        self.area = 3.14 * (radius ** 2)

假设我想在父类中实现诸如translate(new_center) 之类的方法,该方法将返回一个中心位置与原始对象不同的新对象。因为所有子类的行为方式都应该相同(即属性 self.center 应该改变),所以将 translate() 实现为父类 Shape 的方法是有意义的。

如果我想在每次调用translate() 时返回一个Shape 类型的新对象,我们可以简单地将translate() 定义为Shape 的方法,如下所示:

    def translate(self, new_center):
        return Shape(new_center)

但是,如果任何子类实例调用此方法,则结果将是 Shape 类型,因此原始实例包含的任何其他状态信息,例如 side_lengtharea 用于 Square , 会迷路。此外,translate() 不能定义为

    def translate(self, new_center):
        return self.__class__(new_center)

因为每个子类的构造函数都需要父类构造函数不需要的附加参数。如何在不必覆盖每个子类中的父方法的情况下实现这一点(避免定义父方法的重点)?

【问题讨论】:

【参考方案1】:

您可以复制对象并修改副本:

import copy

class Shape():
  def __init__(self, center):
    self.center = center

  def translate(self, new_center):
    new_shape = copy.copy(self) # Replace with deepcopy if needed
    new_shape.center = new_center

...

【讨论】:

以上是关于Python 3:当子构造函数的参数多于父构造函数时,从继承的方法返回新的子类实例的主要内容,如果未能解决你的问题,请参考以下文章

如何为父类构造函数提供值,其中父构造函数的参数比c#中静态void main的子类多? [关闭]

Flutter 6种构造函数详解

继承父构造函数参数

在java语言里如何在子类中调用父类的有参构造函数

C++提高:拷贝构造函数

C++提高:拷贝构造函数