Являются ли конструкторы не членами класса?

Являются ли конструкторы не членами класса? Если да, то почему они не могут быть унаследованы?

JLS 7.0 говорит, что конструкторы не являются членами и, следовательно, не могут быть унаследованы. Это правда только для Java или это общая парадигма ООП?

Ответ 1

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

Рассмотрим следующий пример:

class Plane{
    public Plane(int passengerCapacity, int cargoCapacity){...}
}
class F18 extends Plane{
    public F18(){
        super(0,0);
        ....
    }
}

Теперь, имеет смысл следующий конструктор?

Plane p = new F18(0,0);

Не совсем, потому что дочерний класс является особым случаем родительского класса. В этом конкретном примере нет смысла предоставлять конструкторы Plane в классе F18; дочерний класс хочет контролировать, как построен родительский класс.

Если конструкторы наследуются и кто-то хочет скрыть родительские конструкторы, они могут попытаться сделать что-то вроде этого:

class F18{
    Plane innerPlane;
    public F18(){
        innerPlane = new Plane(0,0);
    }
}

На самом деле это не решение, потому что в каждом методе и свойстве нужно написать return innerPlane.SomeMethod();, который в значительной степени побеждает цель наследования.

Эти принципы применяются также к другим языкам ООП (например, С#).

Но что, если я действительно хочу наследовать конструкторы во многих дочерних классах...

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

class Plane{
    IPilot Pilot;
    public Plane(int passengerCapacity, int cargoCapacity, IPilot pilot){...}
}

Конструкторы - это способы построения объекта. Вам действительно нужен много дочерний класс, который можно построить таким же образом (и используя ту же логику, поскольку они унаследованы), или класс, который имеет гибкость для замены некоторых его компонентов?

Ответ 2

Понятие наследования конструктора не имеет смысла в большинстве парадигм; вместо этого конструкторы вызываются в обратном порядке наследования, поэтому, например, если у вас есть:

Pidgeon -> Bird -> Animal

Где -> указывает 'inherits from', тогда для построения Pidgeon он сначала вызывает конструктор Animal, затем конструктор Bird и, наконец, конструктор Pidgeon. Если это не так, то вам придется либо инициализировать всех членов класса, который вы наследуете, либо вручную вызываете конструктор базового класса (как вам может быть, в любом случае, если у вас есть определенные параметры для прохождения).

Или, чтобы добавить другое, тогда как обычно функция в производном классе заменяет функцию в базовом классе, конструкторы расширяют функцию в базовом классе.

Ответ 3

Несмотря на то, что вы можете услышать, это не общая парадигма ООП. Я думаю, что есть старые языки ООП, где конструктор был просто нормальным методом. Но в настоящее время многие популярные языки рассматривают конструкторы по-разному, как и другие методы. Это несовершенное решение, приводящее к некоторым обходным решениям, например рекомендация в спецификации Beans иметь только конструкторы без аргументов.