views:

137

answers:

3

I have an abstract class with a single concrete method. In this method I want to use a static class variable from the classes that derive from the one the method is declared in. To do so, I of course have to declare this static variable in the abstract class as well.

When the method is called, the variable is resolved to the one in my abstract base class as opposed to the one in the derived class. Do I need to decorate the derived class' property with an attribute?

Am I trying to do something that is not supported in Java, or am I just missing something?

+12  A: 

You're trying to do something that isn't supported. Fields can't be "overridden" - and static members don't behave polymorphically.

Instead, create abstract properties which can be implemented in the derived classes. They'll have to be instance properties even if they return static variables.

Jon Skeet
"Property" isn't at term used all that much in Java outside of JavaBeans. Technically speaking, you're talking about something like this: `protected abstract SomeType getSomething();` that subclasses would implement, correct?
Mark Peters
@Mark: I don't believe that's true at all. The term "property" is used all over Java as far as I'm aware. JavaBeans codified it, but I've seen it used in many discussions which have nothing to do with JavaBeans. But yes, that method signature is what I'm talking about.
Jon Skeet
So in theory, using Animal<-Dog, Animal<-Cat, etc. If one desired to implement an instance counter for every subclass of Animal using a static (Class) variable to hold the count (incremented in the Class constructor) you have to implement getInstanceCount() for every subclass even though the code is virtually identical (the only difference being the different Class name in each Class ({return Dog.count}, {return Cat.count}). Is this a correct statement? If one day your boss said, make getInstanceCount() return long instead of int.. you'd have to update all 600 getInstanceCount() methods?
new Thrall
AKA - The Template Method Pattern
Robin
@new Thrall: If you have 600 subclasses, you've got bigger problems... In that case you might want to have a `HashMap<Class, Integer>` to make life easier.
Jon Skeet
@Jon Skeet. Good point and in this particular case, an inherited method that updated a super.HashMap variable would definitely make things easier. I'm very curious about the context of the OP's problem since it seems he wants to share common behavior across his subclasses but he wants the state that influences or is influenced by the behavior to be specific to each subclass.
new Thrall
A: 

Depending on what you want to do, you can do:

    Base b = new Sub();
    System.out.println(b.myInt); // will print myInt from Base

    Sub s = new Sub();
    System.out.println(s.myInt); // will print myInt from Sub

, but you likely want Jon's approach.

nolegs
+2  A: 

You can't override variables, only methods. If its likely that a subclass needs to give a different value, add a getter method to the class that does that.

abstract class Foo {
  static private final String someValue = "blah";

  String getSomeValue() {
    return someValue;
  }

  public abstract void someMethod();
}

class Bar extends Foo {
  String getSomeValue() {
    return "somethingElse";
  }

  public void someMethod() {
    String x = getSomeValue();
  }
}
locka