views:

264

answers:

5

Hi guys, I'm learning Java (2nd year IT student) and I'm having a little problem. With inheritance to be precise. Here's the code:

class Bazowa
    {
    public Bazowa(int i)
        {
        System.out.println("konstruktor bazowy 1");
        }

    public Bazowa(int j, int k)
        {
        System.out.println("konstruktor bazowy 2");
        }
    }

class Pochodna extends Bazowa
    {
    /* Pochodna()
        {
        System.out.println("konstruktor pochodny bez parametru");
        } */
    Pochodna(int i)
        {
        super(i);
        System.out.println("konstruktor pochodny z parametrem");
        }
    }

So, the Pochodna class extends the Bazowa class, and my exercise is to make a superclass that has only constructors with parameters and a subclass that has both types (with and without).

When I comment the first constructor in Pochodna class, everything works fine, but I don't really know how to make it work without commenting that part. I guess that I have to somehow call the constructor from the first one, but don't have an idea how to do that.

Any help would be appreciated, Paul

+2  A: 

You need to specify something like this:

Pochodna() 
{
  super(0);
}

The trick here is that since you specify a constructor for the superclass the compiler doesn't create a no-arg constructor for you. When you make your zero-arg constructor in the superclass it tries to call the no-arg constructor in the subclass and fails to find anything.

In short, calling another constructor (either in the superclass or in the same class) in your constructor is not optional. Either you specify another constructor explicitly or a call to the superclass' zero-arg constructor will get inserted.

Nathan Hughes
+3  A: 

Your first constructor from Pochodna calls by default super(), a constructor which you do not have in Bazowa.

You should either call one of the base constructors with 1 or 2 params in Pochodna(), or create a constructor with no parameters in your base class.

EDIT: Since you said you are learning Java, I will add some extra explanations to my answer.

Every class must have a constructor, so when you do not declare one explicitly, the compiler does so for you, creating a default constructor with no parameters. This constructor won’t be added if YOU declare constructors explicitly.

In inheritance, the child class is a “specialization” of the parent. That means that the child class contains the attributes and behavior of the parent class and extends on them. But you do not declare the parent elements again (unless you really want to overwrite stuff). So, when you create an instance of the child, somehow the elements taken from the parent must also be initialized. For this you have the super(...) construct.

The first thing that must be in a child constructor is a call to super(...) so that the elements taken from the parent are properly initialized before the child tries to do something with them (you can also have a call to another of child’s constructor this(...) – in this case, the last child constructor in the calling chain will call super(...) ).

Because of this, the compiler will again add a default call to super() – with no parameters – for you when you do not do so yourself in the child.

In the first constructor of Pochodna, since you did not call super(i) or super(j, k) yourself, a call to super() was placed by default. But in the parent class you explicitly specified constructors, so the default was not created by the compiler. And from here the exception, you end up calling a constructor that does not exist.

Hope this makes it easier to learn Inheritance. Cheers.

dpb
This is a really good explanation.
Ridcully
+1  A: 

Since the base class does not have a parameterless constructor, you will need to call a constructor explicitly using super, providing some kind of a default value.

For example:

Pochodna()
{
    super(0);
    System.out.println("konstruktor pochodny bez parametru");
} 

Alternatively, you can create a protected parameterless constructor in the base class. It will not be directly accessible from the outside, but derived classes will be able to use it.

Thorarin
Why the downvote, if I may ask?
Thorarin
+1  A: 

Other answers handle the call to the super constructor.

Note that you could also do this:

Pochodna() {
    this(0);
    System.out.println("konstruktor pochodny bez parametru");
}

which would call your other constructor for Pochodna. Just another option. Study the output to understand what is happening.

Michael Easter
A: 

As the default constructor is not present in the parent. u have to call the other contructor in the child contructor like Pochodna(){ super(10); }

GK