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

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

Невозможно создать объект, напрямую вызвав конструктор класса abstract. Конструктор класса abstract может быть вызван только из производного класса. Поэтому мне кажется, что конструкторы абстрактного класса должны быть либо protected, либо private-package (последнее для необычных случаев ограничения использования конструктора для производных классов внутри пакета). Однако Java позволяет конструктору класса abstract быть public.

Есть ли какие-либо обстоятельства, в которых полезно объявить конструктор класса abstract public, а не protected или package-private?

Это не совсем дубликат вопроса "Абстрактный модификатор доступа к конструктору классов: вы можете объявить конструктор public; Я хочу знать, есть ли веские причины для этого. Мне кажется, что нет. Я вижу, что С# имеет схожую особенность.

4b9b3361

Ответ 1

Ответ одинаковый для java:

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

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

Поэтому добавление специального правила для модификаторов доступа конструкторов абстрактных классов не добавило бы что-то полезное для языка.


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

public abstract class A {
  public A() {}
}

public class B extends A {}

Итак, мы можем создать B, вызвав new B() - но обратите внимание, что мы все равно создаем B, а не A. И, опять же, не имеет значения, является ли конструктор в A общедоступным или защищенным. Он просто не должен быть закрытым, но компилятор заметит и пожалуется...

На самом деле мы вызываем "невидимый" публичный конструктор по умолчанию на B, который выполняет простой вызов super()...

Ответ 2

Назовите меня еретиком, но... Я вижу по крайней мере одно использование для конструктора в абстрактном классе.

То есть: указать, как выглядят параметры конструктора.

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

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

Ответ 3

У вас может быть открытый конструктор, если вы не определяете его в конструкторе в подклассе. Пример

abstract class Animal {
   String name;
   public void Animal(String name) {
         this.name = name;
   }
}


class Cat extends Animal{
    public String sayMayName() {
       return this.name;
    }
}

myCat = new Cat("tester");

name = myCat.sayMyName();

Если конструктор не определен, будет вызываться конструктор родительского класса, если он не является общедоступным, он не будет работать. Это, я думаю, более элегантно сделано с шаблоном factory, но я использовал его на практике в PHP, и он отлично работает.