3
public abstract class SuperClass {
    public int x, y;
    public static int z;
}

I want every subclass of SuperClass to have the static variable z. Naturally z will contain a different value for each subclass. I'm hoping to avoid defining z in every subclass, since it's going to be a functional dependancy of values x and y; Is this possible?

3
  • No, static variables belong to the class that declares them. The best you can do is hide them. Commented Mar 17, 2014 at 17:08
  • "Naturally z will contain a different value for each subclass" => no it won't... Commented Mar 17, 2014 at 17:11
  • @assylias Sorry. Naturally it should.. Commented Mar 17, 2014 at 17:12

3 Answers 3

4

Unlike instance variables that are "one per instance", static variables are not "one per subclass" - they are "one per declaring class". In other words, subclasses of SuperClass share SuperClass.z, but they cannot "override" it on a class-by-class basis.

It does not mean that you cannot implement it yourself: on way to make your own per-subclass storage of integers is adding a static Map<Class,int> zs to SuperClass, with optional functions for accessing the data:

public abstract class SuperClass {
    public int x, y;
    private static Map<Class,Integer> zs = new HashMap<Class,Integer>();
    protected static int getZ(Class c) {
        Integer res = zs.get(c);
        return res == null ? -1 : res.intValue();
    }
    protected static void setZ(Class c, int v) {
        zs.put(c, v);
    }
}
class SubClassOne extends SuperClass {
    public int getZ() {
        return SuperClass.getZ(SubClassOne.class);
    }
}
class SubClassTwo extends SuperClass {
    public int getZ() {
        return SuperClass.getZ(SubClassTwo.class);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Or I could just put public static int z = x in each subclass. It doesn't result in any more lines of code than your suggestion regardless of how many subclasses I may want, right?
@user2651804 This is correct. The only difference is that the superclass would not have an easy access to a per-subclass repository of zs.
In my case I don't need this. I always planned on accessing the z values from outside classes by referring SubclassA.z, SubclassB.z etc. I probably have some horrible design flaws :P
3

Probably the best way to do this is to have a z() method or similar in the abstract class, and override the method in the subclasses you want.

Example:

public abstract class SuperClass {
  public int x, y;

  protected int z() {
     return 42; // protected so only subclasses can see it - change if required
  }
}


public class SubClassOne extends SuperClass {

  public void foo() {
    // do something...
    int z = z();
    // something else...
  }
}

public class SubClassTwo extends SuperClass {

  @Override
  protected int z() {
    return 1;
  }

  // use z() accordingly
}

4 Comments

I think this is the thing the asker wants. I'd add public static fields to the classes, so that I don't need to have an instance to retrieve the field. An example of this in real world use is Antlr: Lexer has public abstract String[] getTokenNames();, subclasses have public static final String[] tokenNames = {...}; and implement the method.
@SillyFreak Well, what his SubClassTwo does is what I wanted to achieve - just in a smarter way, which isn't possible it seems. It doesn't beat public static z = 1 either, so why do unneccesary code?
there is a very important difference between these two regarding dynamic binding. Consider two instances SuperClass sup; SubClass sub;, and a nonstatic method SuperClass.foo() which accesses z. Both SuperClass and SubClass declare static int z;. sup.foo(); and sub.foo(); will both use SuperClass.z, because of static binding. The behavior you probably expected is that the z accessed depends on the identity of the object, not the class where foo() is declared. If that's what you wanted, then you're fine, but document that decision very well; it might confuse other devs.
Silly Freak - that's a good point. I'm not a fan of static on a general level because of testing reasons, but in this case it could be reasonable.
0

if i understand you correctly then do

public abstract class SuperClass {

  public int x, y, z;
  public SuperClass(int z) {

    this.z = z;

  }

}   

then any class that extends this class inherits z;

1 Comment

maybe even a getter and setter for z.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.