Can an Abstract Class Have a Constructor

Can an abstract class have a constructor?

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.

How to call default constructor of an abstract class in Java

You can use super() in your child class. You cannot create instance of abstract class(you might know that)

  abstract class Parent{
Parent(){
System.out.println("Parent contructor!");
}
}


public class Child extends Parent{

public Child() {
super();
System.out.println("Child contructor!");
}

public static void main(String[] args) {
new Child();
}
}

Even if you do not specify super() in Child class, still the parent class constructor will be called because super() will be put by compiler in default constructor of Child class while generating the .class. If you only have parameterized constructor in Parent class then you will have to explicitly call the parent class constructor by super(..parameter) in your child class constructor . Hope this helps!

Java constructor of an abstract class

If you call super in a subclass, the superclass constructor will run (and thus create an object of that class??) then how come you can accually call super in a subclass of an abstract class?

This part is wrong. When you call super in the subclass constructor, you're just telling to the subclass that it first has to execute the initialization code from the super class (abstract or not), then it will continue executing the code to initialize the current instance of the class being created. This doesn't mean that it will create an instance of the super class in the middle of the creation of the current instance.

Is it good to have a constructor in abstract class?

Yes, it's absolutely fine. Just because the constructor can only be called by derived classes doesn't mean it won't be useful. For example, you might have an abstract class which represents a named entity of some kind - it would make sense to take the name as a constructor parameter.

It would probably be worth making the constructor protected, to make it even more obvious that you can't just call it from elsewhere.

Note that there being a constructor (or multiple constructors) in an abstract class does force derived class constructors to go through it, but it doesn't force the derived classes to have the same constructor signatures. For example:

public abstract class NamedFoo
{
private readonly string name;
public string Name { get { return name; } }

protected NamedFoo(string name)
{
this.name = name;
}
}

public class DerivedFooWithConstantName
{
public DerivedFooWithConstantName() : base("constant name")
{
}
}

In this case the derived class constructor is "removing" a parameter (by providing a constant value as the argument to the abstract class constructor) but in other cases it could "add" parameters that it required, or have a mixture.

Why do abstract classes in Java have constructors?

A constructor in Java doesn't actually "build" the object, it is used to initialize fields.

Imagine that your abstract class has fields x and y, and that you always want them to be initialized in a certain way, no matter what actual concrete subclass is eventually created. So you create a constructor and initialize these fields.

Now, if you have two different subclasses of your abstract class, when you instantiate them their constructors will be called, and then the parent constructor will be called and the fields will be initialized.

If you don't do anything, the default constructor of the parent will be called. However, you can use the super keyword to invoke specific constructor on the parent class.

Call constructor in an abstract class

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

Are there good reasons for a public constructor of an abstract class

The answer is the same for java:

THere's no reason for a public constructor for an abstract class. I'd assume that the reason that the compiler doesn't complain is as simple that they just didn't spend time covering that since it really doesn't matter if it's public or protected. (source)

You can't call a constructor of an abstract class from anything other than a direct subclass.

So adding a special rule for access modifiers of constructors of abstract classes wouldn't add something useful to the language.


One thing that looks like an exception from this rule - if the abstract class only defines a default constructor, then the subclass does not have to implement a constructor: this is legal:

public abstract class A {
public A() {}
}

public class B extends A {}

So we can create a B by calling new B() - but note, that we still create a B and not an A. And, again, it doesn't matter if the constructor in A is public or protected. It just shouldn't be private, but the compiler will notice and complain...

Actually we invoke an "invisible" public default constructor on B which does a simple super() call...



Related Topics



Leave a reply



Submit