1

I am currently studying the concept of "class abstraction" and "extension" and have been wondering:
"If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?"

I understand the fact that extension instances the previous abstract class into the extended one and tries to call the default constructor but have been wondering why it gives out an error.

Is it because the constructor has been parametrized or simply because the empty constructor does not exist?

Does the extends keyword call something along the lines of this?

Object myClass = new AbstractClass();

And the missing parameters are the reason why it gives out an error so something along the lines of this would be correct

Object myClass = new AbstractClass(int foo,float boo);

And if that is it, does the super keyword essentially, if you'll allow me the term, "put" the parameters given in the parenthesis "inside" the constructor?

If that's not it what am I getting wrong? How does it actually work?

  • If your class is abstract you cannot instantiate it with `new` keyword. – Michał Krzywański Jun 21 '19 at 08:26
  • 1
    You pretty much got it. Though it's not so much *the extends keyword* as it is the fact that your class is a subclass of another class. Extends keyword is used at other situations but extending a class, and in this case it doesn't do at all the things you've been discussing here. Being a subclass does them. – kumesana Jun 21 '19 at 08:26
  • Ok, i get it! thanks a lot! So with extends i'm telling my subclass to inherit attribute,constructors and methods of the abstract class? – Matteo Perini Jun 21 '19 at 08:33
  • That seems like a good way of thinking about it to me. From a slightly different angle, you could think of it as that when you declare a class `Foo` with a single constructor that takes one or more parameters, you're 'telling' the compiler that those parameters are essential for the existence of any instance of `Foo`. As an instance of a class that extends `Foo` is fundamentally also an instance of `Foo`, then any instances of the extending class must also require the same parameters - although they could be provided by the extending class, not necessarily by whoever is creating that object. – DaveyDaveDave Jun 21 '19 at 08:34
  • I don't get the question `Does the extends keyword call something along the lines of this?` with the example `Object myClass = new AbstractClass();`. Could you elaborate a bit more here? – lealceldeiro Jun 21 '19 at 08:35
  • @lealceldeiro what I meant is when doing this `public class myClass extends AbstractClass` is it basically doing this `Object myClass = new AbstractClass();` – Matteo Perini Jun 21 '19 at 08:54

4 Answers4

2

You should think of the extends keyword, in this context, as just saying that a class is the subclass of another class, and does nothing else. And that there are rules governing how subclasses and superclasses should work.

When you construct a subclass, you must construct its superclass first. For example, to create a Bird, you must first create an Animal. That makes sense doesn't it? To demonstrate this in code:

class Animal {
    public Animal() {
        System.out.println("Animal");
    }
}

class Bird extends Animal {
    public Bird() {
        System.out.println("Bird");
    }
}

Doing new Bird() will first print Animal and then Bird, because the Animal's constructor is called first, and then the Bird constructor. So actually, the Bird constructor implicitly calls the superclass' constructor. This can be written as:

public Bird() {
    super();
    System.out.println("Bird");
}

Now what happens if the super class does not have a parameterless constructor? Let's say the constructor of Animal now takes a String name as argument. You still need to call the superclass' constructor first, but super() won't work because super() needs a string parameter!

Therefore, the compiler gives you an error. This can be fixed by calling super() explicit with a parameter.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

"If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?"

Because the super class says that it MUST be constructor using that declared constructor and there is no other way around. This applies to every extending class - required constructor must be called.

The same happens with any class when you declare other constructor than default one. For example, having

public class A{
   //no default no-arg ctor here
   public A(String name){
       ....
   }

}

public class B{
  //default no-arg ctor will be created
}

so then

  B b=new B();
    A a=new A(); //// INVALID!
    A a=new A("foobar"); // yeah that is it

The same applies when you are extending classes. To construct child instance, you must first "internally create parent instance" calling super.constructor. Since there is no default constructor, ANY of explicit declared superconstructors must be used.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

When initializing an Object the constructor will always be called. Even if you do not define one constructor there will be a default one without any parameters. So if you define a constructor in the abstract class, you have to call that constructor with super().

If you do not define any constructors, then it will be implicitly called as the default one.

Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107
0

If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?

There is no default constructor available in AbstractClass since you define a parametrised constructor. If you don't define a constructor yourself, a default constructor without arguments is implicitly created. You can manually add such one now or you need to use the only available constructor (which is parametrised) with super().


Example of your code with defining constructor without arguments:

class AbstractClass {
    AbstractClass() {} // added manually since not created implicitly
    AbstractClass(int foo, float boo) {}
}
class RealClass extends AbstractClass {
    RealClass() { } // calls super() implicitly
}
AbstractClass myClass = new RealClass();

Example of your code with calling super() with arguments:

class RealClass extends AbstractClass {
    RealClass() {
        super(1, 2);
    }
}
class AbstractClass {
    AbstractClass(int foo, float boo) {}
}
AbstractClass myClass = new RealClass();
Matt
  • 12,848
  • 2
  • 31
  • 53