Asked  7 Months ago    Answers:  5   Viewed   39 times

Can an abstract class have a constructor?

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

 Answers

41

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.

Tuesday, June 1, 2021
 
pamelus
answered 7 Months ago
19

Because there might be a standard way you want to instantiate data in the abstract class. That way you can have classes that inherit from that class call the base constructor.

public abstract class A{

    private string data;

    protected A(string myString){
      data = myString;
    }

}

public class B : A {

     B(string myString) : base(myString){}

}
Wednesday, June 2, 2021
 
PLPeeters
answered 7 Months ago
24

If none of the instance constructors of the Message class are visible to you (typically because they are all private and you are outside the class, or they are all private or internal and you are outside the assembly), you cannot write a class that inherits from Message. (Well, you could make two instance constructors which chain each other cyclicly with the :this(...) syntax, but that would not be useful).

Note that when you look at the "metadata" (reflection generated pseudo-C# for an assembly you refer), you typically only see the "visible" members, so any private or internal members will not show up. I think you look at the metadata because we see non-abstract (and non-extern) methods whoses bodies are absent (just a semicolon ; there instead of a body { ... }).

The source code of your Message class will have one or more constructors, each private or internal, but when seen from outside the assembly, these are "non-existent".

If the source code of a non-static C# class Message contains no instance constructors, the compiler will generate one automatically. It will be a public parameterless constructor if the class is concrete (i.e. non-abstratc), and a protected one if the class is abstract.

That means that if the source code looks like this:

public abstract class Message
{
  // note: zero non-static constructors here
}

it will be compiled exactly as if it had said:

public abstract class Message
{
  protected Message()
  {
  }
}

and in that case the generated instance constructor is accessible to all classes deriving from Message.

Wednesday, July 7, 2021
 
KingCrunch
answered 5 Months ago
97

Just insert the parameters after the name of the extended class:

JButton b = new JButton(new AbstractAction("This is a button") {

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

Also, you can use an initialization block:

JButton b = new JButton(new AbstractAction() {

    {
       // Write initialization code here (as if it is inside a no-arg constructor)
       setLabel("This is a button")
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 
Sunday, August 15, 2021
 
Dail
answered 4 Months ago
87

Maybe an example help you better. Suppose you want to implement a Graph class which may be have adjacency list or adjacency matrix to represent its nodes. So in abstract you want to "addNode" "addEdge" to this graph at least:

public abstract class Graph
{
    public abstract int addNode();
    public abstract void addEdge(int from, int to);
}

Now you can extend two classes:

public class GraphAdjList extends Graph
{
    private Map<Integer,ArrayList<Integer>> adjListsMap;
    public int addNode()
    {
        //list based implementation 
    }
    public void addEdge(int from, int to)
    {
        //list based implementation
    }
}

public class GraphAdjMatrix extends Graph
{
    private int[][] adjMatrix;
    public int addNode()
    {
        //matrix based implementation 
    }
    public void addEdge(int from, int to)
    {
        //matrix based implementation
    }
}

when you call either of addEdge from these two classes you don't have to worry about the data structure behind it, you just know that you get the result you needed so for example:

Graph g1,g2;
g1 = new GraphAdjList();
g2 = new GraphAdjMatrix();

g1.addEdge(1,2);
g2.addEdge(1,2);

through polymorphism you call two different functions but get the same result as client of the Graph.

Another real life example would be car brakes. As a car client, the manufacturer gives you a pedal to push without knowing what is the implementation of the brake in the back-end. It can be a drum-brake or disc-brake implementation in the back. All you need is to push the brake!

Thursday, August 19, 2021
 
Shawn Allen
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share