3

Is it possible to call a constructor in a abstract class?

I read that this constructor can be called through one of its non-abstract subclasses. But I don't understand that statement. Can anybody explain this with an example?

Duncan Jones
  • 59,308
  • 24
  • 169
  • 227
Mansouritta
  • 146
  • 1
  • 1
  • 10
  • `Abstract classes` are **incomplete** classes, so you can not call its constructor, like you cannot drive car whithout wheel or engine. – Andremoniy Jun 19 '14 at 07:13
  • @Andremoniy You *can* call the constructor of an abstract class, but not by using the "normal" `new _____()` notation. – awksp Jun 19 '14 at 07:14
  • possible duplicate of [Can an abstract class have a constructor?](http://stackoverflow.com/questions/260666/can-an-abstract-class-have-a-constructor) – Burkhard Jun 19 '14 at 07:20
  • @Burkhard Similar question, but it doesn't address what the OP is asking here. – Duncan Jones Jun 19 '14 at 07:20
  • Note: the question "*Is it possible to call a constructor in a abstract class?*" could have been answered with a simple piece of code. Not sure why you didn't test that before asking the question. The second paragraph is a different matter and we're happy to explain that to you. – Duncan Jones Jun 19 '14 at 07:21

5 Answers5

6

You can define a constructor in an abstract class, but you can't construct that object. However, concrete sub-classes can (and must) call one of the constructors defined in the abstract parent class.

Consider the following code example:

public abstract class Test {

    // abstract class constructor
    public Test() {
        System.out.println("foo");
    }

    // concrete sub class
    public static class SubTest extends Test {    
      // no constructor defined, but implicitly calls no-arg constructor 
      // from parent class
    }

    public static void main(String[] args) throws Exception {
        Test foo = new Test(); // Not allowed (compiler error)
        SubTest bar = new SubTest(); // allowed, prints "foo"
    }
}
Duncan Jones
  • 59,308
  • 24
  • 169
  • 227
3

You can't call an abstract class constructor with a class instance creation expression, i.e.

// Invalid
AbstractClass x = new AbstractClass(...);

However, in constructing an object you always go through the constructors of the whole inheritance hierarchy. So a constructor from a subclass can call the constructor of its abstract superclass using super(...). For example:

public class Abstract {
    protected Abstract(int x) {
    }
}

public class Concrete {
    public Concrete(int x, int y) {
        super(x); // Call the superclass constructor
    }
}

As constructors of abstract classes can only be called within subclass constructors (and by chaining one to another within the same class), I typically make them protected... making them public would serve no purpose.

The normal rules apply if you don't specify a super(...) or this(...) call in a concrete subclass constructor - it's equivalent to a super(); statement at the start of a constructor, calling a parameterless constructor in the superclass... so there'd have to be such a constructor.

Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
0

In this example Java program, we have an abstract class Servidor, which has one parametric constructor, which accepts name. Subclass provides that name to superclass while creating concrete instance of Servidor and overriding abstract method start(). Since this program compile and run fine you can definitely say abstract class can have constructors in Java.

public class AbstractConstructorTest {

public static void main(String args[]) {
   Servidor Servidor = new Tomcat("Apache Tomcat");
   Servidor.start();
}

}

abstract class Servidor{ protected final String name;

public Servidor(String name){
    this.name = name;
}

public abstract boolean start();

}

class Tomcat extends Servidor{

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

@Override
public boolean start() {
   System.out.println( this.name + " started successfully");
   return true;
}

}

Output: Apache Tomcat started successfully

ZaoTaoBao
  • 2,379
  • 2
  • 18
  • 28
0

You can obviously do something like:

public class ConcreteClass extends AbstractClass {
    public ConcreteClass(){ // concrete class constructor
        super(); // abstract class constructor
    }
}

A constructor of an abstract class can be used only inside constructors of concrete classes inheriting from it.

davioooh
  • 20,249
  • 33
  • 132
  • 224
0

Abstract and Concrete classes are something like Generalization and Specialization in Java and can be executed using inheritance. Let me explain with a plain and simple example. Say we have a class "DBConnector". It seems to be more generalized class and its meaning less to instantiate the class (which DB you are connecting to, driver vary for each DB right). Hence we can make DBConnector as abstract. That is the reason why we cannot basically instantiate Abstract classes. Now we can create different concrete classes for each database extending the behavior of our concrete class like "OracelDBConnector", "MySQLDBConnector" etc., As we inherit the properties of abstract class into concrete class, we initialize the abstract class properties ideally using abstract class constructor using concrete class constructor using super(parameter list).

Thanks, JK

HJK
  • 1,334
  • 1
  • 9
  • 16