Подтвердить что ты не робот

Конструкторы по умолчанию в Java

Я знаю, что задаю здесь несколько серьезных вопросов...

У меня есть класс Foo и класс Bar, который расширяет Foo. В Foo У меня есть конструктор, который принимает набор параметров, которые он устанавливает в свои поля. Производные классы, такие как Bar, как правило, не нуждаются в этом. Теперь моя IDE дает мне "В Foo нет конструктора по умолчанию. Похоже, что это немного из-за того, что" конструкторы не наследуются". Итак, все хорошо и хорошо, но как мне теперь заставить это работать, не дублируя этот конструктор в каждом классе производных? Я предполагаю, что есть более разумный подход?

4b9b3361

Ответ 1

Используйте конструктор super:

public Bar(int a, double b, ...) {
    super(a, b, ...);
}

Ответ 2

Итак, все хорошо и хорошо, но как мне теперь заставить это работать, не дублируя этот конструктор в каждом классе производных?

Вам нужно дублировать подписи конструктора - если вы хотите, чтобы в подклассе были конструкторы с одинаковыми сигнатурами. Но вам не нужно дублировать код - вы просто привязываетесь к конструктору суперкласса:

public Bar(int x, int y) {
    super(x, y);
    // Any subclass-specific code
}

Конечно, если вы можете выработать параметры суперкласса из другого набора параметров, это прекрасно. Например:

public Bar(int x) {
    super(x, x * 2);
    // Any subclass-specific code
}

Вам действительно нужно выяснить, какая информация требуется для создания Bar, который должен диктовать ваши конструкторы.

Если это проблема, возможно, вы злоупотребляете наследованием. Трудно сказать, конечно, без каких-либо представлений о ваших действительных классах, но вы должны смотреть на использование композиции вместо наследования. Это не панацея, но она может избежать такого рода вещей.

Ответ 3

Нет, нет более "разумного" подхода. Если ваш базовый класс не имеет конструктора по умолчанию, вы должны явно вызвать правильный конструктор из всех дочерних классов.

Примечание. Это не значит, что для классов детей должен быть тот же самый конструктор, что и базовый класс. Например, это совершенно верно:

class Foo {

    protected int a;
    protected int b;

    protected Foo(final int a, final int b) {
        this.a = a;
        this.b = b;
    }
}

class Bar extends Foo {

    protected Bar() {
        super(0,0);
    }
}

Ответ 4

Проблема решается следующим образом:

class Foo{
       Foo(int a, int b){}
}

class Bar extends Foo{
         //Here must be a constructor OR declare a constructor in Foo without parameters
         Bar(){super(1,1)} //this is an example

}

Другое решение:

class Foo{
   Foo(int a, int b){}
   Foo(){}
}

class Bar extends Foo{
}

Помните, что если есть конструктор с параметрами в SuperClass (в данном случае Foo), неявный конструктор в дочернем классе (в этом случае Bar) всегда будет иметь неявный вызов " Супер()" (всегда должен быть один, если явно).

Ответ 5

JVM не будет предоставлять конструктор по умолчанию, если вы предоставили его по причинам дизайна. То, что вы можете сделать, определяет конструктор в Bar с той же сигнатурой и вызовом super().

public Bar(int x,int y) {
    super(x,y);
}

Ответ 6

Если параметры не требуются и/или имеют значения по умолчанию, вы можете определить конструктор по умолчанию (без параметров):

class Foo
{
    public final int DEFAULT_A = 42;
    protected int a;
    protected int b;

    public Foo(final int a, final int b)
    {
        this.a = a;
        this.b = b;
    }

    /* Is equal to new Foo(Foo.DEFAULT_A, 0); */
    pubic Foo()
    {
        this.a = this.DEFAULT_A;
    }

}

class Bar extends Foo {}

class PiBar extends Bar
{
    public final int DEFAULT_A = Math.PI;

}