为什么静态类中的“new”运算符

问题描述 投票:0回答:1

我不太清楚处理是如何组织类的,所以标题可能比较模糊。 (不确定这些类是如何嵌套的)一旦我得到一些反馈并更好地理解这一点,我将更改它以反映我所要求的内容。

如果之前已经回答过这个问题,那是因为我对术语的了解不够多,无法找到答案,而且我已经查过了。

我正在用 Java 编写一个程序(处理 4)。

主程序选项卡“GeometryView”具有常用功能。

ArrayList<Datum> datums = new ArrayList<Datum>();

void setup(){
  size(1400, 900);
  surface.setResizable(true);
  //fullScreen();
  frameRate(120);
}

void draw() {
  background(30);
  stroke(220);
  // main draw functions
}
  

我有一个类,用于保存名为“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;
  }
}

在“new Datum()”线上我收到一条错误消息

“无法访问 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 类中使用 Datum 类而不破坏程序的其他部分?我可以使用哪些术语来更多地了解我正在尝试做的事情?

java class nested processing instantiation
1个回答
0
投票

您可以调用

expressionOfTypeGeometryView.new Datum()
来消除该错误,但会提出一个新问题:如何获得 that。好吧,Datum 实例有这样的引用 - 非静态内部类有一个其外部类型的秘密隐藏字段(这里有一个外部类型,但处理也是隐藏的 - 这里有很多巫术魔法,其中不幸的是,这让这有点复杂)。

不过,为了让代码读起来不那么糟糕,我建议采用这种替代方法。添加到您的 Datum 类:

public Datum newDatum(int x, int y) {
  return new Datum(x, y);
}

这确实有效,因为 Datum 确实具有隐藏字段 - 因此它可以使新的 Datum 对象“开箱即用”,而不需要奇怪的

expr.new Datum
语法。这意味着您需要 Datum 的实例来创建新的 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);
,这让我觉得总体上更具可读性 - 代码现在可以更好地描述意图。

© www.soinside.com 2019 - 2024. All rights reserved.