提问人:Andrew Cline 提问时间:11/18/2023 最后编辑:Andrew Cline 更新时间:11/18/2023 访问量:71
如何在静态类中实例化对象,而无需在处理 [duplicate] 中创建主类的实例
How can I instantiate an object within a static class without creating an instance of the main class in Processing [duplicate]
问:
我正在用 Java 编写一个程序(处理 4)。
处理在后台隐藏了一些东西,这使得这更加复杂。主程序“GeometryView”扩展了 PApplet 类并具有常用功能。(这是在“处理”中创建项目时创建的第一个选项卡)
ArrayList<Datum> datums = new ArrayList<Datum>();
void setup(){
size(1400, 900);
surface.setResizable(true);
//fullScreen();
frameRate(120);
datums.add(new Datum(0,0));
datums.add(new Datum(1,2));
datums.add(new Datum(3,4));
}
void draw() {
background(30);
stroke(220);
if(Functions.convex(datums.get(0),datums.get(1),datums.get(2))){
println("These points are part of a convex corner of geometry");
}
}
我有一个类,用于保存名为“Datum”的 X 和 Y 值。这是“处理”中的一个单独选项卡。
class Datum {
float x;
float y;
Datum(float x, float y){
this.x = x;
this.y = y;
}
void drawDatum(int size){
//print("X = " + this.x + ", Y = " + this.y);
ellipse(this.x, -this.y, size, size);
}
Datum clone(){
return new Datum(x,y);
}
}
在单独的选项卡“函数”下,我有一个静态类,用于保存不同的函数。这是为了简化程序的主要部分,因为我可以调用这些函数而无需实例化类。 (这可能不是正确的方法,但它现在有效。我只需要调用“Functions.funcName();”这也可能是我的问题是什么的线索)
static class Functions{
//...
//other functions
//...
static float crossproduct(Datum a, Datum b) {
return a.x * b.y - a.y * b.x;
}
static boolean convex(Datum a, Datum b, Datum c) {
Datum ab = new Datum(b.x - a.x, b.y - a.y); // Error here on "new Datum(x,y)"
Datum bc = new Datum(c.x - b.x, c.y - b.y);
return crossproduct(ab, bc) > 0;
}
}
在线上
Datum ab = new Datum(b.x - a.x, b.y - a.y);
我收到一个错误,说
“无法访问 GeometryView 类型的封闭实例。必须使用 GeometryView 类型的封闭实例来限定分配。(GeometryView 是主类和项目的名称)。
我读过其他一些提到使 Datum 类静态的帖子,但后来我无法访问内置的处理函数,如 ellipse(),并且出现此错误。
“无法从 PApplet 类型对非静态方法 ellipse(float, float, float, float) 进行静态引用”
void drawDatum(int size){
//print("X = " + this.x + ", Y = " + this.y);
ellipse(this.x, -this.y, size, size); // <---- Error is here
}
另一种解决方案是创建主类的另一个实例来访问 Datum 类。也许这会起作用,但似乎再次实例化整个程序只是为了访问一个简单的类而存在性能问题。
如何在不破坏程序其他部分的情况下在 Functions 类中使用“new Datum(x,y)”?创建对主类的引用可能会导致内存问题,还是只是创建引用?
答:
你可以打电话来消除这个错误,但会打开一个新问题:你如何得到它。好吧,Datum 实例有这样一个引用 - 非静态内部类有一个其外部类型的秘密隐藏字段(这里有一个外部类型,但处理也是隐藏的 - 这里发生了很多巫毒魔法,不幸的是,这有点复杂)。expressionOfTypeGeometryView.new Datum()
不过,为了最终得到的代码读起来不是一场彻底的灾难,我建议采用这种替代方法。添加到 Datum 类:
public Datum newDatum(int x, int y) {
return new Datum(x, y);
}
这确实有效,因为 Datum 确实有隐藏字段 - 因此它可以“开箱即用”地制作新的 Datum 对象,而不需要奇怪的语法。这意味着您需要一个 Datum 实例来创建新的 Datum 对象 - 但您确实有一个实例。expr.new Datum
或者,对于更好的 API,请尝试:
public Datum subtract(Datum other) {
return new Datum(x - other.x, y - other.y);
}
并在您的代码中替换,这让我感到总体上更具可读性 - 代码现在更好地描述了意图。Datum ab = new Datum(b.x - a.x, b.y - a.y);
Datum ab = b.subtract(a);
评论
GeometryView gv = new GeometryView();
new
GeometryView gv = new GeometryView()
GeometryView gv = GeometryView.this;
评论
Functions
ellipse
Datum
static
drawDatum
Supplier
Datum
Datum
drawDatum
crossProduct
Datum
Datum
GeometryView