• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Workaround no "static abstract" methods?

 
Ranch Hand
Posts: 171
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have an abstract class "Engine" which represents a family of calculation engines. It has concrete subclasses "Engine2", "Engine3" etc.
My program needs a way to retrieve a static constant value that is particular to each subclass. I thought the best way to do this would be as follows:
abstract class Engine {abstract static double getValue();}
class Engine3 extends Engine {
private static final double VAL = 3.0;
public static double getValue() { return VAL; }
}
However the stupid compiler will not allow "abstract static" methods! Why not??
One possibility is to make the getValue() method not static. However, instantiating the class takes a lot of memory, and this makes no sense just to retrieve the value of the constant!
There are other ways I tried to do this, but all have their problems. Such as:
abstract class Engine {public static final double VALUE = 0.0;}
class Engine2 extends Engine {public static final double VALUE = 3.0;}
However that won't give the right result for a variable of type Engine (because of the binding of class variables at compile-time).
I am really stuck trying to figure out the best way to implement this! Please give me your suggestions.
Thanks
Geoffrey
[This message has been edited by Geoffrey Falk (edited September 08, 2001).]
 
Ranch Hand
Posts: 403
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A nice way to do this is to put your "constants" into an interface.
By the nature of java interfaces, variables are implicitly public static final.
Then just have your relevant classes that want to use these "constants" implement the interface.
James.
 
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Geoffrey Falk:
However the stupid compiler will not allow "abstract static" methods! Why not??


By the nature of static things, they are class level. Therefore they are resolved at compile time and do not participate in polymorphism. Therefore - no overriding etc.
If you can not override something then you can not make it abstract. The only way abstract stuff works it because some class late will implement it (by overriding it).
 
Cindy Glass
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why not just put a static variable in each class
class Engine2 extends Engine {public static final double VALUE = 3.0;}
and then retrieve it using
double d = Engine2.VALUE;
If you don't know which version of the subclass that you have at any given time, you can use reflection to find out.
Engine eng = AnInstanceOfTheSubclass;
Class myEngine = eng.getClass();
double d = myEngine.VALUE;
 
Geoffrey Falk
Ranch Hand
Posts: 171
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How can that work, when the compiler does not know the class at compile time?
I solved the problem by making the method non-static.
It turns out that I was instantiating the Engine at the wrong place in my code. By instantiating it earlier, I am able to call the non-static method to get the value.
Often, problems like this point to the need to refactor the code...
Thanks for your help.
[This message has been edited by Geoffrey Falk (edited September 06, 2001).]
 
Geoffrey Falk
Ranch Hand
Posts: 171
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
delete
[This message has been edited by Geoffrey Falk (edited September 06, 2001).]
 
Cindy Glass
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Geoffrey Falk:
How can that work, when the compiler does not know the class at compile time?
[This message has been edited by Geoffrey Falk (edited September 06, 2001).]


That is what reflection is all about. Finding out the class at runtime instead of compile time.
Engine eng = AnInstanceOfTheSubclass;
Class myEngine = eng.getClass(); //uses reflection to FIND OUT what class this is
double d = myEngine.VALUE;
 
Geoffrey Falk
Ranch Hand
Posts: 171
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, but "myEngine.VALUE" does not work because (as far as the compiler knows) myEngine is just an object of type Class.
Let me know if you can get this to compile... I couldn't.
Thanks
Geoffrey
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In Cindy's code myEngine is just an object of type Class. It is not an Engine of any sort - it is a Class which represents an Engine subclass. The Class has no VALUE field, so myEngine.VALUE cannot possibly compile. Instead, you could use
<pre>
double d = myEngine.getField("VALUE").getDouble(myEngine);
</pre>
to get the same result (much more slowly).
Using a nonstatic method is surely the preferred solution here, as Geoffrey's second post indicates he has discovered.
 
Geoffrey Falk
Ranch Hand
Posts: 171
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, Jim, that tip might be handy.
Geoffrey

------------------
Sun Certified Programmer for the Java 2 Platform
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic