Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an "abstract field"?

I know abstract fields do not exist in java. I also read this question but the solutions proposed won't solve my problem. Maybe there is no solution, but it's worth asking :)

Problem

I have an abstract class that does an operation in the constructor depending on the value of one of its fields. The problem is that the value of this field will change depending on the subclass. How can I do so that the operation is done on the value of the field redefined by the subclass ?

If I just "override" the field in the subclass the operation is done on the value of the field in the abstract class.

I'm open to any solution that would ensure that the operation will be done during the instantiation of the subclass (ie putting the operation in a method called by each subclass in the constructor is not a valid solution, because someone might extend the abstract class and forget to call the method).

Also, I don't want to give the value of the field as an argument of the constructor.

Is there any solution to do that, or should I just change my design ?


Edit:

My subclasses are actually some tools used by my main program, so the constructor has to be public and take exactly the arguments with which they will be called:

tools[0]=new Hand(this);
tools[1]=new Pencil(this);
tools[2]=new AddObject(this);

(the subclasses are Hand, Pencil and AddObject that all extend the abstract class Tool)

That's why I don't want to change the constructor.

The solution I'm about to use is to slightly change the above code to:

tools[0]=new Hand(this);
tools[0].init();
tools[1]=new Pencil(this);
tools[1].init();
tools[2]=new AddObject(this);
tools[2].init();

and use an abstract getter to acces the field.

like image 841
Jules Olléon Avatar asked Apr 10 '10 13:04

Jules Olléon


People also ask

Can you have abstract fields?

An abstract class may have static fields and static methods. You can use these static members with a class reference (for example, AbstractClass. staticMethod() ) as you would with any other class.

Can you have abstract fields in Java?

Java allows us to define an abstract class to contain these common fields, and declare that each of our three shape classes extends this class. As a naming convention, our abstract classes will have names starting with a capital 'A', much as our interfaces always start with a capital 'I'.

How do you create an abstract class?

To create an abstract class, just use the abstract keyword before the class keyword, in the class declaration. You can observe that except abstract methods the Employee class is same as normal class in Java. The class is now abstract, but it still has three fields, seven methods, and one constructor.

How do you implement an abstract?

To implement features of an abstract class, we inherit subclasses from it and create objects of the subclass. A subclass must override all abstract methods of an abstract class. However, if the subclass is declared abstract, it's not mandatory to override abstract methods.


2 Answers

Also, I don't want to give the value of the field as an argument of the constructor.

Why not? It's the perfect solution. Make the constructor protected and offer no default constructor, and subclass implementers are forced to supply a value in their constructors - which can be public and pass a constant value to the superclass, making the parameter invisible to users of the subclasses.

public abstract class Tool{
    protected int id;
    protected Main main;
    protected Tool(int id, Main main)
    {
        this.id = id;
        this.main = main;
    }
}

public class Pencil{
    public static final int PENCIL_ID = 2;
    public Pencil(Main main)
    {
        super(PENCIL_ID, main);
    }
}
like image 75
Michael Borgwardt Avatar answered Oct 15 '22 07:10

Michael Borgwardt


How about abstract getter/setter for field?

abstract class AbstractSuper {
    public AbstractSuper() {
        if (getFldName().equals("abc")) {
            //....
        }
    }

    abstract public void setFldName();
    abstract public String getFldName();
}

class Sub extends AbstractSuper {
    @Override
    public void setFldName() {
        ///....
    }

    @Override
    public String getFldName() {
        return "def";
    }
}
like image 25
Crozin Avatar answered Oct 15 '22 07:10

Crozin