Questions on static methods

Hi everyone,

I’m trying to get my head around static methods in a class.

Let’s say I want to create the following class:

class MyVector {
  float v1, v2;
  
  MyVector(float v1, float v2) {
    this.v1 = v1;
    this.v2 = v2;
  }
}

Now let’s imagine that I want a way to create a unit vector to the right, something like this:

MyVector createUnitVector() {
  return new MyVector(1, 0);
}

My first guess was to create a static method inside my MyVector class like so:

class MyVector {
  float v1, v2;

  MyVector(float v1, float v2) {
    this.v1 = v1;
    this.v2 = v2;
  }

  public static MyVector createUnitVector() {
    return new MyVector(1, 0);
  }
}

But in order to do so, I need to also make my class static:

static class MyVector {
  ...
}

For now it’s okay, but let’s imagine that I want to add a randomize function:

static class MyVector {

  ...

  public void randomize() {
    v1 = random(1);
    v2 = random(1);
  }
}

Now I can’t do that since the random() function is a non-static method of the PApplet class.

Of course I could simply put my function outside the class like so:

class MyVector {
  float v1, v2;

  MyVector(int v1, int v2) {
    this.v1 = v1;
    this.v2 = v2;
  }

  public void randomize() {
    v1 = random(1);
    v2 = random(1);
  }
}


MyVector createUnitVector() {
  return new MyVector(1, 0);
}

But is there a more “elegant” way to solve this?

Thanks :slight_smile:

1 Like
  • You should know by now that all classes & interfaces inside “.pde” files are nested to a PApplet subclass.
  • But when we declare them as static they behave pretty much like any other vanila top classes like those found in a “.java” file.
  • B/c inner classes in “.pde” files belong to a PApplet subclass, we can access its members directly w/o using the dot . operator.
  • However, when they’re declared as static, non-static members demand a PApplet reference.
  • And if you really need to have static members inside your nested classes, those classes gotta be declared as static as well.
  • Unless they’re merely static compile-time constants.
  • If the above is the case, even inner classes can have those static final fields.
  • But fret not! I’ve got an “elegant” workaround for ya. :joy_cat:

Do like Processing’s 3rd-party libraries: Request a PApplet argument as 1 of its constructor’s parameters: :bulb:

static class MyVector {
  final PApplet p;
  float v1, v2;

  MyVector(final PApplet pa) {
    p = pa;
  }

  void randomize() {
    v1 = p.random(1);
    v2 = p.random(1);
  }
}
3 Likes

Thank you for the answer :slight_smile:

I would have something like this then:

static class MyVector {
  final PApplet pa;
  float v1, v2;

  MyVector(final PApplet pa, float v1, float v2) {
    this.v1 = v1;
    this.v2 = v2;
    this.pa = pa;
  }

  public static MyVector createUnitVector(final PApplet pa) {
    return new MyVector(pa, 1, 0);
  }
  
  public static MyVector createRandomVector(final PApplet pa) {
    return new MyVector(pa, pa.random(1), pa.random(1));
  }

  public void randomize() {
    v1 = pa.random(1);
    v2 = pa.random(1);
  }
}
1 Like

If random() is the only PApplet non-static member you need, you can replace it w/ Math.random(): :robot:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Math.html#random()

Or even Java’s Random class for more flexibility: :coffee:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/util/Random.html

2 Likes

Sure, it was just to illustrate the problem.

I was actually going to do so to fix it but wanted to know how to do otherwise!