Проблема наследования классов в Java, конструкторы с параметрами и без - PullRequest
4 голосов
/ 06 января 2010

Я изучаю Java (студентка 2 курса IT), и у меня возникла небольшая проблема. С наследством, чтобы быть точным. Вот код:

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

Итак, класс Pochodna расширяет класс Bazowa, и мое упражнение заключается в создании суперкласса, который имеет только конструкторы с параметрами, и подкласса, который имеет оба типа (с и без).

Когда я комментирую первый конструктор в классе Pochodna, все работает нормально, но я не знаю, как заставить его работать, не комментируя эту часть. Я предполагаю, что мне нужно как-то вызвать конструктор из первого, но я не знаю, как это сделать.

Любая помощь будет оценена, Пол

Ответы [ 5 ]

8 голосов
/ 06 января 2010

Ваш первый конструктор из Pochodna вызывает по умолчанию super(), конструктор, которого у вас нет в Bazowa.

Вы должны либо вызвать один из базовых конструкторов с 1 или 2 параметрами в Pochodna(), либо создать конструктор без параметров в базовом классе.

РЕДАКТИРОВАТЬ: Поскольку вы сказали, что изучаете Java, я добавлю некоторые дополнительные пояснения к моему ответу.

Каждый класс должен иметь конструктор, поэтому, если вы не объявляете его явно, компилятор делает это за вас, создавая конструктор по умолчанию без параметров. Этот конструктор не будет добавлен, если вы объявите конструкторы явно.

В наследовании дочерний класс является «специализацией» родителя. Это означает, что дочерний класс содержит атрибуты и поведение родительского класса и распространяется на них. Но вы не объявляете родительские элементы снова (если вы действительно не хотите перезаписывать вещи). Поэтому, когда вы создаете экземпляр дочернего элемента, элементы, взятые из родительского элемента, также должны быть инициализированы. Для этого у вас есть конструкция super(...).

Первое, что должно быть в дочернем конструкторе, - это вызов super(...), чтобы элементы, взятые у родителя, были должным образом инициализированы, прежде чем ребенок попытается что-то с ними сделать (вы также можете вызвать другой дочерний конструктор this(...) - в этом случае последний дочерний конструктор в вызывающей цепочке будет вызывать super(...)).

Из-за этого компилятор снова добавит вызов по умолчанию к super() - без параметров - для вас, когда вы сами этого не делаете в дочернем элементе.

В первом конструкторе Pochodna, поскольку вы сами не вызывали super(i) или super(j, k), по умолчанию был выполнен вызов super(). Но в родительском классе вы явно указали конструкторы, поэтому компилятор не создал значение по умолчанию. И отсюда исключение, в итоге вы вызываете несуществующий конструктор.

Надеюсь, это облегчит изучение Наследования. Приветствия.

2 голосов
/ 06 января 2010

Вам нужно указать что-то вроде этого:

Pochodna() 
{
  super(0);
}

Хитрость в том, что поскольку вы указываете конструктор для суперкласса, компилятор не создает конструктор без аргументов. Когда вы создаете конструктор с нулевым аргументом в суперклассе, он пытается вызвать конструктор без аргументов в подклассе и ничего не находит.

Короче говоря, вызов другого конструктора (либо в суперклассе, либо в том же классе) в вашем конструкторе не является обязательным. Либо вы явно укажете другой конструктор, либо будет вставлен вызов конструктора нулевого аргумента суперкласса.

1 голос
/ 06 января 2010

Другие ответы обрабатывают вызов супер-конструктора.

Обратите внимание, что вы также можете сделать это:

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

, который вызвал бы вашего другого конструктора для Походны. Просто еще один вариант. Изучите вывод, чтобы понять, что происходит.

1 голос
/ 06 января 2010

Поскольку базовый класс не имеет конструктора без параметров, вам необходимо явно вызвать конструктор, используя super, предоставляя какое-то значение по умолчанию.

Например:

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

В качестве альтернативы, вы можете создать protected конструктор без параметров в базовом классе. Он не будет напрямую доступен извне, но производные классы смогут его использовать.

0 голосов
/ 06 января 2010

Поскольку конструктор по умолчанию отсутствует в родительском конструкторе, необходимо вызвать другой конструктор в дочернем конструкторе:

Pochodna() {
    super(10);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...