Наследование конструктора Java

Так же для log4net. Я добавляю свои два бита, потому что для фактического использования, имеет смысл смотреть на некоторые реализации с открытым исходным кодом для наблюдения примеров кода реального мира с некоторыми удобными дополнениями. Для log4net я предложил бы первое, что пришло на ум смотреть подтекст . Особенно смотрите на приложение, запускаются и assemblyinfo биты.

179
задан Michael Celey 21 March 2013 в 03:48
поделиться

9 ответов

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

FileInputStream stream = new FileInputStream();

делать?

Теперь, возможно, должен быть способ простого создания сквозных конструкторов, которые довольно распространены, но я не думаю, что это должно быть по умолчанию. Параметры, необходимые для создания подкласса, часто отличаются от параметров, требуемых суперклассом.

197
ответ дан 23 November 2019 в 20:13
поделиться

Когда вы наследуете от Super, на самом деле происходит вот что:

public class Son extends Super{

  // If you dont declare a constructor of any type, adefault one will appear.
  public Son(){
    // If you dont call any other constructor in the first line a call to super() will be placed instead.
    super();
  }

}

Итак, это причина, потому что вам нужно вызвать свой уникальный конструктор, поскольку "Super" не имеет по умолчанию.

Теперь, пытаясь угадать, почему Java не поддерживает наследование конструкторов, вероятно, потому, что конструктор имеет смысл только в том случае, если он говорит о конкретных экземплярах, и вы не должны иметь возможность создавать экземпляр чего-либо, когда вы не Не знаю, как это определяется (полиморфизмом).

30
ответ дан 23 November 2019 в 20:13
поделиться

Потому что создание вашего объекта подкласса может быть выполнено другим способом, чем ваш суперкласс. Возможно, вы не хотите, чтобы клиенты подкласса могли вызывать определенные конструкторы, доступные в суперклассе.

Глупый пример:

class Super {
    protected final Number value;
    public Super(Number value){
        this.value = value;
    }
}

class Sub {
    public Sub(){ super(Integer.valueOf(0)); }
    void doSomeStuff(){
        // We know this.value is an Integer, so it's safe to cast.
        doSomethingWithAnInteger((Integer)this.value);
    }
}

// Client code:
Sub s = new Sub(Long.valueOf(666L)): // Devilish invocation of Super constructor!
s.doSomeStuff(); // throws ClassCastException

Или даже проще:

class Super {
    private final String msg;
    Super(String msg){
        if (msg == null) throw new NullPointerException();
        this.msg = msg;
    }
}
class Sub {
    private final String detail;
    Sub(String msg, String detail){
        super(msg);
        if (detail == null) throw new NullPointerException();
        this.detail = detail;
    }
    void print(){
        // detail is never null, so this method won't fail
        System.out.println(detail.concat(": ").concat(msg));
    }
}
// Client code:
Sub s = new Sub("message"); // Calling Super constructor - detail is never initialized!
s.print(); // throws NullPointerException

Из этого примера вы видите, что вам понадобится способ объявить, что «Я хочу унаследовать эти конструкторы» или «Я хочу унаследовать все конструкторы, кроме для них ", а затем вам также нужно будет указать предпочтение наследования конструктора по умолчанию на тот случай, если кто-то добавит новый конструктор в суперкласс ... или вы можете просто потребовать, чтобы вы повторили конструкторы из суперкласса, если хотите" наследовать "их, что, возможно, является более очевидным способом сделать это.

11
ответ дан 23 November 2019 в 20:13
поделиться

Поскольку конструкторы являются деталью реализации - они вообще не могут быть вызваны пользователем интерфейса / суперкласса. К тому времени, как они получат экземпляр, он уже будет построен; и наоборот, в то время, когда вы создаете объект, по определению нет переменной, которой он в настоящее время назначен.

Подумайте, что означало бы заставить все подклассы иметь унаследованный конструктор. Я утверждаю, что проще передавать переменные напрямую, чем классу «волшебным образом» иметь конструктор с определенным количеством аргументов только потому, что это делает его родительский элемент.

5
ответ дан 23 November 2019 в 20:13
поделиться

Ответ Дэвида правильный. Я хотел бы добавить, что вы можете получить знак от Бога, что ваш дизайн испорчен, и что «Сын» не должен быть подклассом «Супер», но вместо этого у Супер есть некоторые детали реализации, лучше всего выраженные имея функциональность, которую предоставляет Сон, как своего рода стратегию.

РЕДАКТИРОВАТЬ: Ответ Джона Скита потрясающий.

2
ответ дан 23 November 2019 в 20:13
поделиться

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

0
ответ дан 23 November 2019 в 20:13
поделиться

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

-1
ответ дан 23 November 2019 в 20:13
поделиться

Конструкторы не полиморфны.
Имея дело с уже созданными классами, вы можете иметь дело с объявленным типом объекта или любым из его подклассов. Вот для чего полезно наследование.
Конструктор всегда вызывается для определенного типа, например new String () . Гипотетические подклассы в этом не играют.

2
ответ дан 23 November 2019 в 20:13
поделиться

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

Вот обсуждение того же вопроса, касающегося C #. По общему мнению, это усложнит язык, приведет к появлению неприятных побочных эффектов при изменении базового класса и, как правило, не является необходимым при хорошем дизайне.

-1
ответ дан 23 November 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: