How to create a class variable in an abstract class ?

edited October 2015 in How To...

Hello, actually my problem is a bit wider than that : I have an abstract class A and several other classes that extends A, let's picking of these and call it B. I want to store in an ArrayList named All every B that is created during the execution of the program, except for some specific cases where I don't want B to be in All. I want to be able to do something like A.All.get(i). I tried to declare the field All static but I got the error : "The field All cannot be declared static; static fields can only be declared in static or top level types".

Can you help me with that ?

Answers

  • Can you post an MCVE?

  • void setup()
    {
      B b1 = new B("temp");
      println(A.All.size()); // supposed to print 0
      B b2 = new B();
      println(A.All.size()); // supposed to print 1
    }
    
    void draw(){}
    
    abstract class A
    {
      static ArrayList< A > All = new ArrayList< A >();
    }
    
    class B extends A
    {
      B(){All.add(this);} // here I want B to be in the ArrayList All
      B(String temp){} // here I don't want B to be in the ArrayList All
    }
    
  • Processing puts all of your code into a class with the same name as your sketch, so your A and B classes become inner classes of that class.

    Inner classes can't have static variables, unless those variables are initialized. So you've got a few options:

    • Make your A class static: static abstract class A.
    • Put your A class in its own .java tab, that way Processing doesn't turn it into an inner class.
    • Move the all variable to the sketch level instead of inside the A class.

    There are probably other options, but they all come down to a slight redesign.

  • In my sketch, class A has its own .pde file therefore its own tab. Does it make any difference with a .java file ?

  • A .pde file has an "invisible" class that Processing adds around all of your code.

    Let's say this is your sketch:

    void setup(){
       //whatever
    }
    void draw(){
       //whatever
    }
    abstract class A{
      //whatever
    }
    

    And let's say you name that sketch MySketch.pde. What Processing generates is this:

    public class MySketch extends PApplet{
    
        void setup(){
           //whatever
        }
        void draw(){
           //whatever
        }
        abstract class A{
          //whatever
        }
    }
    

    That's why your A class is an inner class. Putting it in its own .java tab prevents Processing from making it an inner class.

  • edited October 2015

    This mini-game uses some static abstract classes w/ static fields: :ar!
    https://forum.Processing.org/two/discussion/8997/hoppy-beaver

  • edited October 2015

    In short, we can create nested static classes, abstract or not, and have some non-static (a.K.a. inner) class extends it.

  • Eventually I solved my problem, instead of declaring this field static in the abstract class, I created another class that is dedicated to manage this ArrayList and other things, so no other class will need to access this ArrayList. @KevinWorkman thank you for your answers, it is good to know how it works :)

    @GoToLoop in my abstract class I have some methods I cannot declare static so I think this cannot work. And I don't get the point of creating a static abstract class with two fields, can you explain to me ?

  • edited November 2015

    Since we can't have static members inside inner classes unless they're final primitives or String w/ compile time known values, that's why I've decided to split my classes as 1 static & the other non-static:

    static abstract class BeaverStatic {
      static final int SIZE = 40, GROUND = SIZE+10, SPD = 5;
      static PImage falling, jumping;
    }
    
    class Beaver extends BeaverStatic {
      boolean isJumping;
      int x, y;
    
      // ...
    }
    

    As you can notice above, I've moved every static member to BeaverStatic.
    And then I've used extends in Beaver so it inherits all of those static members! *-:)
    In the end, Beaver now has all of those static members for itself too, even though it is prohibited to be directly declared inside it! :ar!

    A final note, BeaverStatic doesn't need to be abstract at all.
    It is there just to impede it of being directly instantiated inadvertently.
    B/c it is an incomplete class after all. :-\"

  • Ok thanks :)

Sign In or Register to comment.