Can an abstract class have a constructor? If so, how it can be used and for what purposes?
Consider this:
abstract class Product {
int value;
public Product( int val ) {
value= val;
}
abstract public int multiply();
}
class TimesTwo extends Product {
public int mutiply() {
return value * 2;
}
}
The superclass is abstract and has a constructor.
Yes it can have a constructor and it is defined and behaves just like any other class's constructor. Except that abstract classes can't be directly instantiated, only extended, so the use is therefore always from a subclass's constructor.
Consider this:
abstract class Product {
int multiplyBy;
public Product( int multiplyBy ) {
this.multiplyBy = multiplyBy;
}
public int mutiply(int val) {
return muliplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a default constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.
NOTE: As there is no default (or no-arg) constructor in the parent abstract class the constructor used in subclasses must be specified.
Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.
You would define a constructor in an abstract class if you are in one of these situations:
- you want to perform some initialization (to fields of the abstract class) before the instantiation of a subclass actually takes place
- you have defined final fields in the abstract class but you did not initialize them in the declaration itself; in this case, you MUST have a constructor to initialize these fields
Note that:
- you may define more than one constructor (with different arguments)
- you can (should?) define all your constructors protected (making them public is pointless anyway)
- your subclass constructor(s) can call one constructor of the abstract class; it may even have to call it (if there is no no-arg constructor in the abstract class)
In any case, don't forget that if you don't define a constructor, then the compiler will automatically generate one for you (this one is public, has no argument, and does nothing).