Abstract variables in Java?

JavaClassVariablesAbstract

Java Problem Overview


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.

  • I define variable TABLENAME in abstract, but no value given.
  • I create a clsContactGroups, I should be prompted to implement TABLENAME, this is where gets some data. eg: TABLENAME="contactgroups";
  • I create a second class clsContacts, I should be prompted to implement TABLENAME, this is where gets some data. eg: TABLENAME="contacts";
    etc...

Java Solutions


Solution 1 - Java

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;
}

Solution 2 - Java

I think your confusion is with C# properties vs. fields/variables. In C# you cannot define abstract fields, even in an abstract class. You can, however, define abstract properties as these are effectively methods (e.g. compiled to get_TAG() and set_TAG(...)).

As some have reminded, you should never have public fields/variables in your classes, even in C#. Several answers have hinted at what I would recommend, but have not made it clear. You should translate your idea into Java as a JavaBean property, using getTAG(). Then your sub-classes will have to implement this (I also have written a project with table classes that do this).

So you can have an abstract class defined like this...

public abstract class AbstractTable {

    public abstract String getTag();
    public abstract void init();

    ...
}

Then, in any concrete subclasses you would need to define a static final variable (constant) and return that from the getTag(), something like this:

public class SalesTable extends AbstractTable {

    private static final String TABLE_NAME = "Sales";

    public String getTag() {
        return TABLE_NAME;
    }

    public void init() {
        ...
        String tableName = getTag();
        ...
    }

}

EDIT:

You cannot override inherited fields (in either C# or Java). Nor can you override static members, whether they are fields or methods. So this also is the best solution for that. I changed my init method example above to show how this would be used - again, think of the getXXX method as a property.

Solution 3 - Java

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.

Solution 4 - Java

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.

Solution 5 - Java

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

Solution 6 - Java

As there is no implementation of a variable it can't be abstract ;)

Solution 7 - Java

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.

Solution 8 - Java

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.

Solution 9 - Java

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.

Solution 10 - Java

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);
    }
}

Solution 11 - Java

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.

Solution 12 - Java

public abstract class Duck 
{
    /** This is not static. */
    private String duckName = "";

    /** Abstract Constructor. */
    public Duck(final String name) 
    {
        duckName = name;
    }

    /** Accessor method. */
    public String getName()
    {
         return duckName;
    }

    /** An example of an abstract method that has to be made concrete. */
    public abstract void fly(); 

}

Then you will have another class:

public class KhakiCampbell extends Duck
{
    // Constructor
    public KhakiCampbell(final String name)
    {
        super(name);
    }

    @Override
    public void fly()
    {
        /** Do something simple. */
       System.out.println(getName() + " is flying!");
    }
 
    /** This is something that only Khaki Cambell ducks do, of course, joke!. */
    public void crash()
    {
       /** Do something simple. */
       System.out.println(getName() + " has crashed!");
    }
 
    /** Keep going. */
    public void stillFly()
    {
        /** Do something simple. */
        System.out.println(getName() + " is still flying!");
    }

    public static void main(String[] args)
    {
        KhakiCampbell  duck = new KhakiCampbell("Bella");
        KhakiCampbell  mavis = new KhakiCampbell("Mavis");
        KhakiCampbell  boris = new KhakiCampbell("Boris");
        duck.fly();
        mavis.fly();
        boris.crash();
        mavis.stillFly();
    }
}

I ran the above code after putting it into separate file names of Duck.java and KhakiCampbell.java of course. After running KhakiCampbell in eclipse I saw the following on the java console:
Bella is flying!
Mavis is flying!
Boris has crashed!
Mavis is still flying!

I hope this answers your questions. You do not need any static variable declarations.

Solution 13 - Java

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?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPentium10View Question on Stackoverflow
Solution 1 - JavaBalusCView Answer on Stackoverflow
Solution 2 - JavaKevin BrockView Answer on Stackoverflow
Solution 3 - JavaduffymoView Answer on Stackoverflow
Solution 4 - JavaPadmaragView Answer on Stackoverflow
Solution 5 - JavaLomboView Answer on Stackoverflow
Solution 6 - JavaTomas VanaView Answer on Stackoverflow
Solution 7 - JavaErich KitzmuellerView Answer on Stackoverflow
Solution 8 - JavadimitarvpView Answer on Stackoverflow
Solution 9 - JavaJoachim SauerView Answer on Stackoverflow
Solution 10 - Javauser531069View Answer on Stackoverflow
Solution 11 - JavaShark DengView Answer on Stackoverflow
Solution 12 - Javauser96279View Answer on Stackoverflow
Solution 13 - JavaJoachim SauerView Answer on Stackoverflow