gpt4 book ai didi

python - 试图理解面向对象的编程。如何使用对象组合?

转载 作者:行者123 更新时间:2023-12-03 19:42:34 27 4
gpt4 key购买 nike

做两类Point()Circle()定义如下:

class Point:
def __init__(self, x, y):
self._x = x
self._y = y

@property
def x(self):
return self._x

@x.setter
def x(self, x):
self._x = x

@property
def y(self):
return self._y

@y.setter
def y(self, y):
self._y = y

def __repr__(self):
return f"{self._x}, {self._y}"

def move(self, x, y):
self._x = x
self._y = y
return self._x, self._y


class Circle:
def __init__(self, radius, x, y):
self._radius = radius
self.x = x
self.y = y

def move(self, x, y):
Point.move(self, x, y)

def __repr__(self):

return f"radius = {self._radius}, \nx = {self.x},\ny = {self.y}"


point1 = Point(12, 3)
print(point1)
point1.y = 0
print(point1)

point1.move(55, 7)
print(point1)

circle1 = Circle(4, 1, 1)
print(circle1)
circle1.move(2, 2)
print(circle1)


我已经尝试开发方法 move(x,y)在 Circle 中,从 Point 类调用方法 move(x,y),而不使用继承。首先初始化一个对象:
circle1 = Circle(4,1,1)

但是当你使用 circle1.move(2,2)圆圈位置还是(1,1):怎么了?
我想用_x和_y来模拟私有(private)变量!

最佳答案

问题是你没有使用“组合”——你只是随机调用 Point.move在你的 circle 类的方法中。该调用将失败,因为如果放在其他任何地方都会失败:Point.move是一个实例方法,它需要一个点的实例来处理。

对于“组合”,您需要拥有作为您的类属性的另一个类的实例 - 然后在需要时调用这些实例上的方法。

例如,您的“圆”可能有一个“.center”属性,即一个点。然后,您只需调用 circle.center.move在一个实例中 - 或者,如果你想要一个 .move circle类本身的方法:


class Circle:
def __init__(self, radius, x, y):
self._radius = radius
self.center = Point(x, y)

def move(self, x, y):
self.center.move(x, y)

def __repr__(self):
return f"Circle center at ({self.point}), radius: {self.radius}"

你想做什么

您的代码试图调用 Point 中的方法传递 Circle 的实例.虽然 Python 3 允许这样做,但这完全是巧合,它几乎可以工作(如果 Circle 中的“x”和“y”名称与“Point”中的名称相同,那么它会像 Dani 的回答中所展示的那样工作) - 但是这不是“OOP”也不是“Composition”,并且不会引发运行时错误,因为 Python 3 将类中的实例方法视为函数。

“圆”不是“点”。考虑几何,你可以说“Circle”和“Point”有一些属性和方法——Python允许你通过使用多重继承来共享这些,我们称之为“mixins”——所以你可以有一个“LocationMixin”类这将具有“x”和“y”属性,以及“move”方法,并且是“Point”和“Circle”的祖先,这将起作用。

简化代码

除了您的组合问题之外,重要的是要注意,在 Python 中,尝试将属性设为“私有(private)”并不重要,并为公共(public) consunption 定义 getter 和 setter -
如果它简单地写成,你的点类也可以工作:

class Point:
def __init__(self, x, y):
self.x = x
self.y = y

def __repr__(self):
return f"{self.x}, {self.y}"

def move(self, x, y):
self.x = x
self.y = y
return self.x, self.y

如果您想验证 x 和 y ae 是否设置为数字或验证值范围,getter 和 setter 将是有意义的 - 否则,它们只是多余的。

有趣的是,Python 设计了它的“属性”,以便您可以更改属性以具有 getter 和 setter,并在稍后添加这些验证,而不会破坏与类 (Point) 的先前版本的任何兼容性。

关于python - 试图理解面向对象的编程。如何使用对象组合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61047154/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com