Этот код повторяющийся, а не СУХОЙ и бесполезный (ИМХО)... в связи с этим снова возникает вопрос:
Почему java не поддерживает наследование конструкторов? Есть ли какая-либо выгода в том, чтобы не разрешать это наследование?
Переведено автоматически
Ответ 1
Предположим, что конструкторы были унаследованы ... тогда, поскольку каждый класс в конечном итоге является производным от Object, каждый класс в конечном итоге получит конструктор без параметров. Это плохая идея. Чего именно вы ожидали бы:
FileInputStreamstream=newFileInputStream();
что делать?
Теперь потенциально должен существовать способ простого создания конструкторов "сквозного доступа", которые довольно распространены, но я не думаю, что это должно быть по умолчанию. Параметры, необходимые для создания подкласса, часто отличаются от параметров, требуемых суперклассом.
Ответ 2
Когда вы наследуете от Super, это то, что происходит на самом деле:
publicclassSonextendsSuper{
// If you dont declare a constructor of any type, adefault one will appear. publicSon(){ // If you dont call any other constructor in the first line a call to super() will be placed instead. super(); }
}
Итак, в этом причина, потому что вы должны вызвать свой уникальный конструктор, поскольку у "Super" нет конструктора по умолчанию.
Теперь попытаемся угадать, почему Java не поддерживает наследование конструктора, вероятно, потому, что конструктор имеет смысл, только если речь идет о конкретных экземплярах, и вы не сможете создать экземпляр чего-либо, если не знаете, как это определено (с помощью полиморфизма).
Ответ 3
Потому что построение вашего объекта подкласса может выполняться иным способом, чем построение вашего суперкласса. Возможно, вы не хотите, чтобы клиенты подкласса могли вызывать определенные конструкторы, доступные в суперклассе.
classSub { publicSub(){ super(Integer.valueOf(0)); } voiddoSomeStuff(){ // We know this.value is an Integer, so it's safe to cast. doSomethingWithAnInteger((Integer)this.value); } }
// Client code: Subs=newSub(Long.valueOf(666L)): // Devilish invocation of Super constructor! s.doSomeStuff(); // throws ClassCastException
Или еще проще:
classSuper { privatefinal String msg; Super(String msg){ if (msg == null) thrownewNullPointerException(); this.msg = msg; } } classSub { privatefinal String detail; Sub(String msg, String detail){ super(msg); if (detail == null) thrownewNullPointerException(); this.detail = detail; } voidprint(){ // detail is never null, so this method won't fail System.out.println(detail.concat(": ").concat(msg)); } } // Client code: Subs=newSub("message"); // Calling Super constructor - detail is never initialized! s.print(); // throws NullPointerException
Из этого примера вы видите, что вам понадобится какой-то способ объявить, что "Я хочу наследовать эти конструкторы" или "Я хочу наследовать все конструкторы, кроме этих", а затем вам также нужно будет указать предпочтение наследования конструктора по умолчанию на случай, если кто-то добавит новый конструктор в суперкласс... или вы могли бы просто потребовать, чтобы вы повторяли конструкторы из суперкласса, если вы хотите их "наследовать", что, возможно, является более очевидным способом сделать это.
Ответ 4
Поскольку конструкторы являются деталью реализации, пользователь интерфейса / суперкласса вообще не может их фактически вызывать. К моменту получения экземпляра он уже сконструирован; и наоборот, на момент создания объекта по определению нет переменной, которой он в данный момент присвоен.
Подумайте о том, что означало бы заставить все подклассы иметь унаследованный конструктор. Я утверждаю, что понятнее передавать переменные напрямую, чем для класса "волшебным образом" иметь конструктор с определенным количеством аргументов только потому, что это делает его родительский элемент.