0

I have below two classes ,

    abstract class Shape {
   protected DrawAPI drawAPI;

   protected Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
   }
   public abstract void draw(); 
}

class Circle extends Shape {
   private int x, y, radius;

   public Circle(int x, int y, int radius, DrawAPI drawAPI) {
      //super(drawAPI);
      this.x = x;  
      this.y = y;  
      this.radius = radius;
   }

   public void draw() {
      drawAPI.drawCircle(radius,x,y);
   }
}

I get an error in the constructor of Circle class if I don't add the commented line (//super(drawAPI)) . The error is constructor shape in class shape cannot be applied to given types. Actual and formal arguments Differ in length

I want to know why adding commented line fix the problem and what does it do ?

lasan
  • 365
  • 2
  • 5
  • 13
  • Possible duplicate of [Why do this() and super() have to be the first statement in a constructor?](https://stackoverflow.com/questions/1168345/why-do-this-and-super-have-to-be-the-first-statement-in-a-constructor) – Janez Kuhar Apr 22 '18 at 14:11

5 Answers5

1

The Shape class has a unique constructor and it doesnot take any parameter. Thus, the call should simply be super();.

Zelig63
  • 1,592
  • 1
  • 23
  • 40
  • And so what is `protected Shape(DrawAPI drawAPI){ this.drawAPI = drawAPI; }` ? – davidxxx Apr 22 '18 at 14:05
  • Don't see this other constructor in the Android dev site https://developer.android.com/reference/android/graphics/drawable/shapes/Shape.html – Zelig63 Apr 22 '18 at 14:26
  • The question is not Android tagged .I think that it is a custom Drawable class otherwise the OP would not have this behavior at compile time. – davidxxx Apr 22 '18 at 14:30
1

Check out this link, Java uses chaining for constructor calling, it will by default call the no parameter constructor implicitly, but if the parent class doesn't have the no params constructor (and it has other constructors) you will need to call one of the other constructors explicitly.

Akhadra
  • 419
  • 3
  • 10
  • 1
    Just to add to this answer, if the parent abstract class had no constructor, then a default no parameter constructor would be assumed by Java. But because there is a constructor, and it does have parameters, then it has to be called from the child class. – Jose Martinez Apr 22 '18 at 14:08
1

Shape already has a constructor method, so no default constructor method exists.

Bellamy
  • 11
  • 1
1

I think you should visit the documentation for understanding it better.

If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.

As in your case Shape does not have a default constrcutor, you need to explicitly mention super class with argument

Using the Keyword super

Nitishkumar Singh
  • 1,781
  • 1
  • 15
  • 33
1

I want to know why adding commented line fix the problem and what does it do ?

The first statement of a constructor has to invoke the constructor of its parent class if it has a parent class (right for all classes but Object).
Shape is the parent of Circle. So the Shape constructor has to be invoked first in Circle constructor.
The problem is that the Shape constructor doesn't have a no arg constructor as you defined one with an argument.
So consequently you have to explicit invoke this constructor.

Note that the compiler adds the super() invocation as first statement of the constructor body if the parent constructor is not explicitly invoked.
So as the parent constructor has no arg, you don't need to invokesuper() in the class source code. The compiler will do it for you in the compiled class.
But in your actual case, the compiler cannot add super() as the parent class doesn't have a no arg constructor.
It would produce this constructor invocation that is not valid :

public Circle(int x, int y, int radius, DrawAPI drawAPI) {
  super(); // Shape with no arg constructor doesn't exist
  this.x = x;  
  this.y = y;  
  this.radius = radius;
}

So the compiler expects you specify the invocation of a parent class constructor that is actually defined :

public Circle(int x, int y, int radius, DrawAPI drawAPI) {
  super(drawAPI); 
  this.x = x;  
  this.y = y;  
  this.radius = radius;
}
davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • So when we make an object of a child class that means the constructor of the parent class get invoked right ? means parent object is made automatically ? – lasan Apr 22 '18 at 14:26
  • Indeed. Note that you don't have two objects as you instantiate a child class. You have just the child object but the child object creation relies on the the invocation of the constructor of the parent class (while it doesn't create a parent instance) – davidxxx Apr 22 '18 at 14:28