Reputation: 1231
I am writing an app about Twisty Puzzles: the Rubik Cube, Pyraminx, Skewb and the like. I have an abstract class 'TwistyPuzzle' and derived classes: TwistyCube, TwistyPyraminx, etc. I have a dialog which provides basic information about each puzzle: it's name, its inventor, year of invention, basic description how the puzzle works.
This information about each puzzle is - IMHO - best kept inside each of the 'implementation' classes TwistyCube, TwistyPyraminx, etc. Static methods force themselves:
class TwistyCube extends TwistyPuzzle
static String getName()
{
return "Rubik Cube";
}
but there seems to be no way to have the Dialog, which needs to display this information, query the classes - because there's no concept of an 'abstract static' method in Java.
So what are my options? What is the standard workaround for the lack of 'abstract static' in Java?
Upvotes: 1
Views: 201
Reputation: 719376
As you noted, you cannot declare an abstract static
method (or field).
This is not just syntax. The fundamental reason is that Java static
members are not inherited. And that means that static
members cannot normally be used polymorphically. When you call a static
method or access a static
field, the decision of which classes member is called / used is determined at compile time, based solely on compile time type considerations.
So ... basically ... what you are trying to do cannot be done.
But there is a solution. If you want to use abstract
on a method, declare it as an instance method. Whether you are doing this so that you can use the method polymorphically ... or for other reasons.
You argued against this by saying:
A method like that should be non-static because you'll always call it on an instance. – Thomas 2 hours ago
Of course not - the name of all instances of 'TwistyRubik' is the same. It clearly belongs to the class, not its instances. – Ralf Kleberhoff 1 hour ago
But I think you are missing the point. Methods don't "belong" to instances. Methods belongs to classes. Even non-static methods. We call non-static methods "instance" methods because they typically operate on the state of a specific instance. But they don't need to. And instance method can return information about the class it belongs to.
Here's how I would write your example:
public abstract class TwistyPuzzle {
public abstract String getName();
...
}
public class TwistyCube extends TwistyPuzzle
public String getName();
return "Rubik Cube";
}
...
}
So lets analyze this:
Q: Does it have the desired behavior?
A: Yes. Every TwistyCube
instance will return "Rubik Cube"
.
Q: Is there any space overhead of making this a non-static method?
A: No. Method code is shared, and since Java doesn't treat methods as updatable properties of an instance, there is no per-object storage overhead.
Q: Is there an performance overhead in making this a non-static method?
A: In most cases No. And if there is an overhead, then it is minimal.
Q: Are there advantages over a static
method?
A: Yes. The getName()
can be used polymorphically with runtime method dispatching.
So what is the actual problem here? What does "belong" mean?
Frankly, I think it is just about the way that you have conceptualized instance methods. The fact that you called a method on an instance doesn't mean that it needs to return information specific to that instance.
Think of Java as a tool. Use it the way it was designed to be used. If you want abstract
(e.g. polymorphic) methods that deliver information about the current Java class, then this is the standard way to do it.
FOLLOWUP
How about a separate enum - one value per one type of a
TwistyPuzzle
- that would provide such info?
I guess that would work. But now you have the problem of getting the correct enum
value that relates to a specific TwistyPuzzle
instance (or class) that you are enquiring about. And you have a readability / maintainability issue with information pertaining to each TwistyPuzzle
class living in a separate class; i.e. the enum
.
Upvotes: 2