寒假回家时,我将尝试使用Processing 编程语言(Java 风格)制作一些很酷的东西。对于我的第一个项目,我想定义一个自定义 Line 类,以便更轻松地在线进行数学计算。在Python中,它会是这样的:
import numpy as np
class Line():
def __init__(self, x1, y1, x2, y2):
self.x1, self.x2 = x1, x2
self.y1, self.y2 = y1, y2
@property
def p1(self):
return np.array([self.x1, self.y1])
@property
def p2(self):
return np.array([self.x2, self.y2])
这样,如果 x1, ..., y2 改变,相应的点 vector 也会改变。显然这个例子效率有点低,但重点仍然存在。在javascript中,我知道Object.defineProperty(obj, prop,descriptor)
,但不清楚
- 如何在处理中做到这一点
- 这是发挥作用的地方。定义类时的等效操作是什么?
编辑:澄清为什么 @property
特别有用:
假设我希望以两种方式表示线条,这两种方式都将由 Line 对象存储:
- 一,普通版本:两个点,p1 和 p2,每个点由一个 x、y 坐标组成。
- 两个具有两个点 u 和 v 的参数化版本,使得 p1 = u 和 p2 = u + v,线段上的任何点由 u + t * v 给出,其中 t 是 0 和 之间的标量1.
如果p2改变,v也会改变,反之亦然。更改 p1 将更改 u 和 v。有些数学在参数化版本方面更容易完成,而有些在普通版本方面更容易完成,所以我希望对任何属性所做的任何更改都能正确进行更新其他属性,使 p1、p2 和 u、v 始终代表相同的行。
在 python 中,我可以修改属性的 setter 和 getter 方法以适本地解释所有这些,但我似乎无法确定在处理中执行此操作的方法。
最佳答案
如果您只使用常规的处理对象和语法,您几乎会自动得到这个。
例如,您可以使用两个 PVector
实例来定义端点。
class Line{
PVector p1;
PVector p2;
public Line(float x1, float y1, float x2, float y2){
p1 = new PVector(x1, y1);
p2 = new PVector(x2, y2);
}
}
然后,如果您想更改其中一个端点,您只需直接访问 PVector
实例即可:
Line myLine = new Line(0, 10, 25, 100);
println(myLine.p1.x + ", " myLine.p1.y);
myLine.p1.x = 750;
println(myLine.p1.x + ", " myLine.p1.y);
您还可以获得 PVector class 中已定义的所有数学内容。 .
您可以通过将 PVector
变量设为最终变量或仅允许 Line
类的用户通过随后访问 >PVector
实例。
编辑:我会尝试在这里回答您的其他问题。
is public necessary?
这具体取决于您如何使用此类、您希望其他人如何访问它等等。您可以在the Processing reference中了解这一点。 ,或者只是谷歌搜索“java访问修饰符”之类的东西。或者您可以尝试将其取出,看看会发生什么。
what if I want both the vanilla definition of a line (x1, y1, x2, y2) and the parameterized (u1, u2, v1, v2, s.t. x1 = u1 and x2 = u1 + v1, etc) versions simultaneously? In this case, and importantly, if x2 is updated, so should v1 be updated.
我不太确定你在这里问什么。当您编写类时,您可以决定如何表示您的状态以及如何让人们与该状态互动。
例如,我上面的示例使用两个 PVector
实例来表示线条,它允许人们直接与它们交互以修改该线条。但我可以添加一个函数,让他们将一条线定义为一个点、一个角度和一个距离。我只需要确保计算出第二点,这样我就可以存储我的状态。像这样的事情:
class Line{
PVector p1;
PVector p2;
public Line(float x1, float y1, float x2, float y2){
p1 = new PVector(x1, y1);
p2 = new PVector(x2, y2);
}
public Line(PVector origin, float angle, float distance){
p1 = origin;
p2 = new PVector(origin.x + cos(angle)*distance, origin.y + sin(angle)*distance);
}
}
请注意,第二个构造函数允许用户以完全不同的方式指定一行,但我仍然将状态存储为两个 PVector
实例。如果稍后需要,您可以存储 angle
和 distance
值,并且您可以拥有允许用户修改它们的 setter - 您只需更新您的 PVector
相应的值。
关于java - Python @property 在处理类声明中的等效项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34422009/