I am coming from c# where this was easy, and possible.
I have this code:
public abstract class clsAbstractTable {
public abstract String TAG;
public abstract void init();
}
but Eclipse tells me I use illegal modifier.
I have this class:
public class clsContactGroups extends clsAbstractTable {
}
I want the variable and method defined in such way, that Eclipse to prompt me, I have unimplemented abstract variables and methods.
How do I need to define my abstract class so I should be prompted to implement the abstracts?
EDIT 1
I will create different classes for different db tables. Each class should have it's own TABLENAME variable, no exception. I have to make sure this variable is static each time when I create a new class that extends the abstract class.
Then in the abstract class I will have a method eg: init();
If in this init() method I call TABLENAME, it should take the value from the sub-class.
something like this should also work out
String tablename=(clsAbstract)objItem.TABLENAME;
// where objItem can be any class that extended clsAbstract;
EDIT 2
I want a constant(static) defined in each class having it's name defined in abstract.
As there is no implementation of a variable it can't be abstract ;)
No, Java doesn't support abstract variables. It doesn't really make a lot of sense, either.
What specific change to the "implementation" of a variable to you expect a sub class to do?
When I have a abstract
String
variable in the base class, what should the sub class do to make it non-abstract?
Why do you want all subclasses to define the variable? If every subclass is supposed to have it, just define it in the superclass. BTW, given that it's good OOP practice not to expose fields anyway, your question makes even less sense.
No such thing as abstract variables in Java (or C++).
If the parent class has a variable, and a child class extends the parent, then the child doesn't need to implement the variable. It just needs access to the parent's instance. Either get/set or protected access will do.
"...so I should be prompted to implement the abstracts"? If you extend an abstract class and fail to implement an abstract method the compiler will tell you to either implement it or mark the subclass as abstract. That's all the prompting you'll get.
Just add this method to the base class
public abstract class clsAbstractTable {
public abstract String getTAG();
public abstract void init();
}
Now every class that extends the base class (and does not want to be abstract) should provide a TAG
You could also go with BalusC's answer
Use enums to force values as well to keep bound checks:
enum Speed {
HIGH, LOW;
}
private abstract class SuperClass {
Speed speed;
SuperClass(Speed speed) {
this.speed = speed;
}
}
private class ChildClass extends SuperClass {
ChildClass(Speed speed) {
super(speed);
}
}
The best you could do is have accessor/mutators for the variable.
Something like getTAG()
That way all implementing classes would have to implement them.
Abstract classes are used to define abstract behaviour not data.
Define a constructor in the abstract class which sets the field so that the concrete implementations are per the specification required to call/override the constructor.
E.g.
public abstract class AbstractTable {
protected String name;
public AbstractTable(String name) {
this.name = name;
}
}
When you extend AbstractTable
, the class won't compile until you add a constructor which calls super("somename")
.
public class ConcreteTable extends AbstractTable {
private static final String NAME = "concreteTable";
public ConcreteTable() {
super(NAME);
}
}
This way the implementors are required to set name
. This way you can also do (null)checks in the constructor of the abstract class to make it more robust. E.g:
public AbstractTable(String name) {
if (name == null) throw new NullPointerException("Name may not be null");
this.name = name;
}
In my experiment, Java abstract class does need to specify abstract keyword. Reversely, error that "abstract modifier cannot be put here" will be prompted. You can specify abstract attributes just like ordinary attributes.
public abstract class Duck implements Quackable, Observable {
// observerList should keep the list of observers watching this duck
List<Observer> observerList;
public AttackBehavior attackBehavior;
public FlyBehavior flyBehavior;
public Duck() {
observerList = new ArrayList<Observer>();
}
}
And in subclass, you can directly use these attributes this.flyBehavior
or this.attackBehavior
. You don't need to rewrite the attributes in attribute field.
To add per-class metadata, maybe an annotation might be the correct way to go.
However, you can't enforce the presence of an annotation in the interface, just as you can't enforce static members or the existence of a specific constructor.
Change the code to:
public abstract class clsAbstractTable {
protected String TAG;
public abstract void init();
}
public class clsContactGroups extends clsAbstractTable {
public String doSomething() {
return TAG + "<something else>";
}
}
That way, all of the classes who inherit this class will have this variable. You can do 200 subclasses and still each one of them will have this variable.
Side note: do not use CAPS as variable name; common wisdom is that all caps identifiers refer to constants, i.e. non-changeable pieces of data.
Source: Stackoverflow.com