我有几何形状的面向对象编程模型。如果要添加两个几何形状,但在每个子类中都有定义,则我在每个类中都有 add 方法。 如何在父类中实现 add方法,这样就不必为每个子类都定义它了?
none
答案 0 :(得分:1)
这是一个奇怪的问题,因为添加两个圆并使其成为半径总和的新圆并没有多大意义。添加int
的行为也很奇怪,因为您正在更改对象的状态,而不是像添加对象时那样创建新对象。
但是实际上,有一种方法可以使用父类中的一种方法,使用某些特定于Python的功能来实现此目的:
cls = self.__class__
是当前对象的类,可用于创建相同类的新对象,并测试other
是否是正确的类型。d = self.__dict__
是对象属性的字典。**{ ... }
拆包运算符允许使用字典理解来调用cls
构造函数以计算参数。__repr__
来显示对象的状态,以便于在REPL中方便地测试示例。这是一个例子:
class Shape:
def __add__(self, other):
cls = self.__class__
d = self.__dict__
if isinstance(other, int):
return cls(**{ k: v + other for k, v in d.items() })
elif isinstance(other, cls):
return cls(**{ k: v + other.__dict__[k] for k, v in d.items() })
else:
raise TypeError()
def __radd__(self, other):
return self.__add__(other)
def __repr__(self):
d = self.__dict__
return '{0}({1})'.format(
self.__class__.__name__,
', '.join('{0}={1!r}'.format(k, v) for k, v in d.items())
)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
class Rectangle(Shape):
def __init__(self, width, height):
self.width, self.height = width, height
示例:
>>> Circle(4) + Circle(5)
Circle(radius=9)
>>> Circle(6) + 2
Circle(radius=8)
>>> 3 + Circle(2)
Circle(radius=5)
>>> Rectangle(2, 3) + Rectangle(4, 5)
Rectangle(width=6, height=8)
>>> Rectangle(2, 3) + 1
Rectangle(width=3, height=4)
>>> 5 + Rectangle(2, 3)
Rectangle(width=7, height=8)
请注意,我已将行为更改为始终返回一个新对象,而不是对现有对象进行突变。