666

Can an abstract class have a constructor?

If so, how can it be used and for what purposes?

Community
  • 1
  • 1
Szere Dyeri
  • 13,926
  • 10
  • 35
  • 40

22 Answers22

693

Yes, an abstract class can have a constructor. Consider this:

abstract class Product { 
    int multiplyBy;
    public Product( int multiplyBy ) {
        this.multiplyBy = multiplyBy;
    }

    public int mutiply(int val) {
       return multiplyBy * 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 constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.

Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.

NOTE: As there is no default (or no-arg) constructor in the parent abstract class, the constructor used in subclass must explicitly call the parent constructor.

rimsky
  • 1,063
  • 2
  • 15
  • 24
Michael Rutherfurd
  • 12,752
  • 5
  • 25
  • 40
  • 83
    @Jonathon: No real benefit is gained by adding complexity for the purposes of the answering the question asked. If the question was about scope, then, yes, it would make sense to contrast the three useful possibilities. – Michael Rutherfurd Jun 21 '10 at 00:50
  • 36
    I think all Jonathon was trying to say is that a public constructor on an abstract class doesn't make any sense because you can't instantiate an abstract class directly (can only instantiate through a derived type that itself is not marked as abstract). – Hobo Spider Apr 17 '14 at 21:10
  • 7
    The constructor in 'TimesTwo' is not a default constructor. – Lew Bloch Sep 03 '14 at 00:09
  • 1
    I think it would be good to clarify the last sentence, to state that this is only in this example, that generally abstract classes have default constructors if none have been explicitly declared – Vic Seedoubleyew Aug 11 '16 at 14:24
  • 2
    Along similar lines to the NOTE and Vic's comment, if an abstract class `extends` another class which doesn't have a default constructor, then the abstract class must have a constructor which calls the non-default constructor of the class it's extending. – Andy Royal Nov 01 '17 at 15:13
  • Java newbie here.. If the subclass is in a different package than the abstract class, then having a public constructor makes sense, doesn't it? so that the subclass can call super().. – Uncaught Exception Jan 09 '19 at 10:45
  • @UncaughtException, in that case a protected constructor would make more sense than a public constructor. – Silwing Aug 07 '19 at 13:04
  • @HoboSpider From my experience, abstract class constructors make sense for deserialization of objects using Jackson, for example. Because Jackson requires an empty constructor, code outside of your control (or code you do not want to change) that do not have one can be changed with an abstract class. For example, add a default, empty constructor to any class by using a “mixin” to make ObjectMapper happy `ObjectMapper.addMixIn(Concrete.class, MixinAbstract.class)`. – Jonathan Komar Nov 19 '19 at 07:08
  • @MichaelRutherfurd If we can't create the abstract class constructor then in sub class cusntructor how it is possible to invoke it?? – chirag soni Aug 25 '20 at 12:54
169

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).

jfpoilpret
  • 10,170
  • 2
  • 26
  • 31
69

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.

Lawrence Dol
  • 59,198
  • 25
  • 134
  • 183
55

Yes! Abstract classes can have constructors!

Yes, when we define a class to be an Abstract Class it cannot be instantiated but that does not mean an Abstract class cannot have a constructor. Each abstract class must have a concrete subclass which will implement the abstract methods of that abstract class.

When we create an object of any subclass all the constructors in the corresponding inheritance tree are invoked in the top to bottom approach. The same case applies to abstract classes. Though we cannot create an object of an abstract class, when we create an object of a class which is concrete and subclass of the abstract class, the constructor of the abstract class is automatically invoked. Hence we can have a constructor in abstract classes.

Note: A non-abstract class cannot have abstract methods but an abstract class can have a non-abstract method. Reason is similar to that of constructors, difference being instead of getting invoked automatically we can call super(). Also, there is nothing like an abstract constructor as it makes no sense at all.

Yoon5oo
  • 489
  • 5
  • 11
Aniket Thakur
  • 58,991
  • 35
  • 252
  • 267
  • 13
    note on saying _... constructor of the abstract class is automatically invoked ..._ that this is only true for the default constructor of the abstract class, others would have to be explicitly invoked through super(args). – antiplex Aug 14 '13 at 12:10
  • 2
    Non-default constructors can be automatically invoked, provided that they are no-arg constructors. So it is not only true for default constructors. – Lew Bloch Sep 03 '14 at 00:11
15

Not only can it, it always does. If you do not specify one then it has a default no arg constructor, just like any other class. In fact, ALL classes, including nested and anonymous classes, will get a default constructor if one is not specified (in the case of anonymous classes it is impossible to specify one, so you will always get the default constructor).

A good example of an abstract class having a constructor is the Calendar class. You get a Calendar object by calling Calendar.getInstance(), but it also has constructors which are protected. The reason its constructors are protected is so that only its subclasses can call them (or classes in the same package, but since it's abstract, that doesn't apply). GregorianCalendar is an example of a class that extends Calendar.

MattC
  • 4,968
  • 1
  • 42
  • 37
7

An abstract class can have a constructor BUT you can not create an object of abstract class so how do you use that constructor?

Thing is when you inherit that abstract class in your subclass you can pass values to its(abstract's) constructor through super(value) method in your subclass and no you don't inherit a constructor.

so using super you can pass values in a constructor of the abstract class and as far as I remember it has to be the first statement in your method or constructor.

Yoon5oo
  • 489
  • 5
  • 11
Alok
  • 123
  • 1
  • 5
6

Yes it can, abstract classes constructors are generally used for super calls for initialization events common to all the subclasses

Jacob
  • 61
  • 1
  • 1
5

Although there are many good answers, I would like to give my 2 cents.

Constructor DOES NOT BUILD THE OBJECT. It is used to initialize an object.

Yes, an Abstract class always has a constructor. If you do not define your own constructor, the compiler will give a default constructor to the Abstract class. Above holds true for all classes - nested, abstract, anonymous, etc.

An abstract class (unlike interface) can have non-final non-static fields which need initialization. You can write your own constructor in the abstract class to do that. But, in that case, there won't be any default constructor.

public abstract class Abs{
    int i;
    int j;
    public Abs(int i,int j){
        this.i = i;
        this.j = j;
        System.out.println(i+" "+j);
    }
}

Be careful while extending above abstract class, you have to explicitly call super from each constructor. The first line of any constructor calls to super(). if you do not explicitly call super(), Java will do that for you. Below code will not compile:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    System.out.println("2 arg");
}
}

You have to use it like below example:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    super(i,j);
    System.out.println("2 arg");
}
}
Yoon5oo
  • 489
  • 5
  • 11
Harshil
  • 995
  • 13
  • 20
4

Of Course, abstract class can have a constructor.Generally class constructor is used to initialise fields.So, an abstract class constructor is used to initialise fields of the abstract class. You would provide a constructor for an abstract class if you want to initialise certain fields of the abstract class before the instantiation of a child-class takes place. An abstract class constructor can also be used to execute code that is relevant for every child class. This prevents code duplication.

We cannot create an instance of an abstract class,But we can create instances of classes those are derived from the abstract class. So, when an instance of derived class is created, the parent abstract class constructor is automatically called.

Reference :This Article

Raj Baral
  • 605
  • 5
  • 19
3

Yes, Abstract Classes can have constructors !

Here is an example using constructor in abstract class:

abstract class Figure { 

    double dim1;        
    double dim2; 

    Figure(double a, double b) {         
        dim1 = a;         
        dim2 = b;         
    }

    // area is now an abstract method 

   abstract double area(); 

}


class Rectangle extends Figure { 
    Rectangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for rectangle 
    double area() { 
        System.out.println("Inside Area for Rectangle."); 
        return dim1 * dim2; 
    } 
}

class Triangle extends Figure { 
    Triangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for right triangle 
    double area() { 
        System.out.println("Inside Area for Triangle."); 
        return dim1 * dim2 / 2; 
    } 
}

class AbstractAreas { 
    public static void main(String args[]) { 
        // Figure f = new Figure(10, 10); // illegal now 
        Rectangle r = new Rectangle(9, 5); 
        Triangle t = new Triangle(10, 8); 
        Figure figref; // this is OK, no object is created 
        figref = r; 
        System.out.println("Area is " + figref.area()); 
        figref = t; 
        System.out.println("Area is " + figref.area()); 
    } 
}

So I think you got the answer.

Elrond_EGLDer
  • 47,430
  • 25
  • 189
  • 180
Ketan G
  • 487
  • 1
  • 4
  • 19
2

As described by javafuns here, this is an example:

public abstract class TestEngine
{
   private String engineId;
   private String engineName;

   public TestEngine(String engineId , String engineName)
   {
     this.engineId = engineId;
     this.engineName = engineName;
   }
   //public gettors and settors
   public abstract void scheduleTest();
}


public class JavaTestEngine extends TestEngine
{

   private String typeName;

   public JavaTestEngine(String engineId , String engineName , String typeName)
   {
      super(engineId , engineName);
      this.typeName = typeName;
   }

   public void scheduleTest()
   {
     //do Stuff
   }
}
Brad Larson
  • 168,330
  • 45
  • 388
  • 563
jaideep
  • 1,541
  • 16
  • 19
2

In a concrete class, declaration of a constructor for a concrete type Fnord effectively exposes two things:

  • A means by which code can request the creation of an instance of Fnord

  • A means by which an instance of a type derived from Fnord which is under construction can request that all base-class features be initialized.

While there should perhaps be a means by which these two abilities could be controlled separately, for every concrete type one definition will enable both. Although the first ability is not meaningful for an abstract class, the second ability is just as meaningful for an abstract class as it would be for any other, and thus its declaration is just as necessary and useful.

supercat
  • 69,493
  • 7
  • 143
  • 184
2

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.

S.Lott
  • 359,791
  • 75
  • 487
  • 757
  • 8
    I know that this is an old post but this code section will not compile. The subclass TimesTwo should implement the non default constructor. – MikeL May 11 '13 at 11:37
  • This is a compilation error ... TimesTwo must implemet call a super constructor in order to implement that abstract class.... – V. Sambor Jun 05 '16 at 13:19
  • 1
    This code will not compile, as you don't have default constructor in Product class, and your TimesTwo has default constructor. Default constructor of TimesTwo will call default constructor of class Product with super(), which will result in compilation error. – Harshil Sep 06 '17 at 12:12
2

yes it is. And a constructor of abstract class is called when an instance of a inherited class is created. For example, the following is a valid Java program.

// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
    }
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
    }

class Main {
public static void main(String args[]) { 
   Derived d = new Derived();
    }

}

This is the output of the above code,

Base Constructor Called Derived Constructor Called

references: enter link description here

chamzz.dot
  • 442
  • 2
  • 10
  • 18
1

Abstract class can have a constructor though it cannot be instantiated. But the constructor defined in an abstract class can be used for instantiation of concrete class of this abstract class. Check JLS:

It is a compile-time error if an attempt is made to create an instance of an abstract class using a class instance creation expression.

A subclass of an abstract class that is not itself abstract may be instantiated, resulting in the execution of a constructor for the abstract class and, therefore, the execution of the field initializers for instance variables of that class.

akhil_mittal
  • 18,855
  • 7
  • 83
  • 82
1

In order to achieve constructor chaining, the abstract class will have a constructor. The compiler keeps Super() statement inside the subclass constructor, which will call the superclass constructor. If there were no constructors for abstract classes then java rules are violated and we can't achieve constructor chaining.

Yoon5oo
  • 489
  • 5
  • 11
1

Yes, an Abstract Class can have a Constructor. You Can Overload as many Constructor as you want in an Abstract Class. These Contractors Can be used to Initialized the initial state of the Objects Extending the Abstract Class. As we know we can't make an object of an Abstract Class because Objects are Created by the "new" keywords and not by the constructors...they are there for only initializing the state of the subclass Objects.

Yoon5oo
  • 489
  • 5
  • 11
Shubhamhackz
  • 4,435
  • 2
  • 31
  • 56
1

Since an abstract class can have variables of all access modifiers, they have to be initialized to default values, so constructor is necessary. As you instantiate the child class, a constructor of an abstract class is invoked and variables are initialized.

On the contrary, an interface does contain only constant variables means they are already initialized. So interface doesn't need a constructor.

Yoon5oo
  • 489
  • 5
  • 11
Arun Raaj
  • 1,520
  • 1
  • 15
  • 19
0

Yes surely you can add one, as already mentioned for initialization of Abstract class variables. BUT if you dont explicitly declare one, it anyways has an implicit constructor for "Constructor Chaining" to work.

Kedar Parikh
  • 1,096
  • 10
  • 18
0

The purpose of the constructor in a class is used to initialize fields but not to "build objects". When you try to create a new instance of an abstract SuperClass, the compiler will give you an error. However, we can inherit an abstract class Employee and make use of its constructor by setting its variables See example below

public abstract class Employee {
  private String EmpName;
  abstract double calcSalary();

  Employee(String name) {
    this.EmpName = name;// constructor of abstract class super class
  }
}

class Manager extends Employee{
 Manager(String name) {
    super(name);// setting the name in the constructor of sub class
 }
double calcSalary() {
    return 0;
 }
}
karto
  • 3,163
  • 8
  • 40
  • 63
0

package Test1;

public class AbstractClassConstructor {

public AbstractClassConstructor() {

}

    public static void main(String args[]) {
       Demo obj = new Test("Test of code has started");
       obj.test1();
    }

}

abstract class Demo{
    protected final String demoValue;

    public Demo(String testName){
        this.demoValue = testName;
    }

    public abstract boolean test1();
}

class Test extends Demo{

    public Test(String name){
        super(name);
    }

    @Override
    public boolean test1() {
       System.out.println( this.demoValue + " Demo test started");
       return true;
    }

}
sachit
  • 31
  • 1
-5

Yes..It is like any other class. It can have a constructor and it is called after creating object for the base class.

Sandeep
  • 21
  • 5