В чем разница между абстрактным и защищенным в моем сценарии - С#

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

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

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

Ответ 1

состояния MSDN об использовании ключевого слова abstract для классов: используйте абстрактный модификатор в объявлении класса, чтобы указать, что класс предназначен только для классов быть базовым классом других классов. То есть, не требуется, чтобы абстрактный класс содержал абстрактные элементы. Модификатор abstract - это просто явный способ сказать, что класс не должен быть создан, а не с техническими препятствиями, такими как создание невидимых конструкторов.

Обратите внимание, что описанное вами техническое препятствие даже имеет оговорку: его все еще можно назвать:

  • Он может быть вызван из производных классов.
  • Его можно вызвать с помощью отражения.

Оба означают, что другие разработчики, которые просто (ab -?), используя ваш класс, могут делать то, чего вы не намеревались, а именно создать экземпляр своего класса, и оба они не могут быть при создании абстрактного класса.

Следовательно, ответ заключается в том, что вы должны пометить свои классы как abstract.

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

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

Следовательно, также создайте любые конструкторы ваших абстрактных классов (не более) protected.

Ответ 2

Я бы сделал публичный абстрактный класс с защищенным конструктором.

Использование abstract дает понять, что это действительно абстрактный класс. Просто конструктор protected не так понятен.

Ничто иное, как подкласс может вызвать конструктор abstract; это не имеет смысла оставлять его public.

Ответ 3

Частный или защищенный конструктор все еще может быть вызван статическими методами в объявляющем классе. Для абстрактного класса должен быть создан производный класс. Например, шаблон singleton использует частные конструкторы, вызванные открытым статическим методом/свойством.

Ответ 4

Открытый абстрактный класс с защищенным или внутренним конструктором передает, как вы хотите, чтобы код вызывал его. Использование не доступного конструктора может на самом деле запутать.