How do I specify that an implementing class must contain a particular field?
I would like to write an abstract class (or interface) which either
- Forces all implementing classes to provide a field (ideally static) of a particular type an开发者_Python百科d name (maybe by throwing a compile-time error if it's missing?), or
- Automatically provides such fields in implementing classes.
An example would be:
public abstract class A {
abstract int counter;
}
public class B extends A {
public int getCounter() {
return counter;
}
}
in which case B's getCounter()
method would return a (static or instance) counter
specific to the B
class, and not a value inherited from A
. Is there any way to do this in Java?
There is not really a good way to do that, nor do I believe there should be. You can accomplish the same thing using abstract methods and writing your algorithms in the base class so that they take advantage of the delegated methods.
Perhaps if you provide more details on why you think you need to do this, we can help you craft a more correct solution.
For example:
public abstract class A {
protected abstract int getCounter();
public void doStuff() {
int counter = getCounter();
for (int i=0; i < counter; i++) {
// do stuff
}
}
}
Make a HashMap with the class as key, and the counter as value.
An interface's main purpose is not to tell its implementors what to do. It is to tell other classes what its implementors can do. Also, it should not specify any implementation details. That said, it shouldn't and can't impose any variable declarations.
If you want a per-subclass counter, then declare a Map
in the superclass, with key=subclass's Class
, and value=the counter value (as suggested by
Thorbjørn Ravn Andersen's answer)
Try one of the many tools listed here:
http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#Java
I am assuming this is in a development environment with multiple developers.
As others have pointed out, this isn't directly possible in the language without a fair amount of extra work.
My suggestion is that you follow Pace's suggestion: instead of specifying a counter, specify it as a method in an interface.
The only difference I'd suggest is that you rename it to something which more correctly reflects your intention. Something like:
protected abstract getNumberOfInstancesOfThisClass();
You could even code up an automated unit test generator to check that it's been correctly implemented, something you'd have to do even if you could create a static member in an abstract class.
public abstract class A {
private static Map<Class,Integer> map = new HashMap<Class,Integer>();
protected A() { map.put(this.getClass(), 0); }
public int getCounter() { return map.get(this.getClass()); }
public void setCounter(int n) { map.put(this.getClass(), n); }
}
public class B extends A {
...
}
精彩评论