ChatGPT解决这个技术问题 Extra ChatGPT

Can an abstract class have a constructor?

Can an abstract class have a constructor?

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


r
rimsky

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.


@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.
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).
The constructor in 'TimesTwo' is not a default constructor.
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
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.
j
jfpoilpret

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


Bonus for making them protected. It adds that nice bit of completeness.
L
Lawrence Dol

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.


Y
Yoon5oo

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.


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).
Non-default constructors can be automatically invoked, provided that they are no-arg constructors. So it is not only true for default constructors.
M
MattC

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.


Y
Yoon5oo

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.


J
Jacob

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


R
Raj Baral

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


Y
Yoon5oo

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

Constructor DOES NOT BUILD THE OBJECT. It is used to initialize the fields.
R
ROMANIA_engineer

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.


B
Brad Larson

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

Cut-and-pasted from geekinterview.com/question_details/77988. Plagiarism is not cool.
s
supercat

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.


c
chamzz.dot

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


S
S.Lott

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.


I know that this is an old post but this code section will not compile. The subclass TimesTwo should implement the non default constructor.
This is a compilation error ... TimesTwo must implemet call a super constructor in order to implement that abstract class....
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.
Either the abstract class needs a default no arg constructor or it's concrete class should call super(val) i.e. call the parent class's parameterized constructor with and int parameter.
K
Kedar Parikh

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.


a
akhil_mittal

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.


Y
Yoon5oo

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.


Y
Yoon5oo

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.


Y
Yoon5oo

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.


k
karto

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

e
exhuma
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;
    }
   
}

S
Sandeep

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


it' is not like any other class. It can not be instantiated like any other class.