Создание «public» создает контракт, который будет обязательным для всех унаследованных классов. Создание «защищенного» создает контракт с непосредственно - унаследованные классы, но не заставляет классы делать такой контракт доступным для любого из их потомков.
Если вы ожидаете, что исходный код базового класса будет доступен для всех, кто наследует его, и ожидает, что базовый класс никогда не изменится (как правило, это означает, что причиной использования базового класса является разрешение публичные члены и свойства базового класса, которые должны использоваться взаимозаменяемо с производными классами, а не уменьшать количество кода, необходимого для производных классов), и если все общедоступные методы являются виртуальными или напрямую связаны с виртуальными методами, нет большого недостатка в используя защищенные поля, а не защищенные виртуальные геттеры/сеттеры. Если класс потомка должен изменить способ использования полей, он может просто переопределить все используемые им методы.
Если вы ожидаете, что производные классы могут быть созданы в ситуациях, когда классы, находящиеся выше их в иерархии, не полностью известны или не являются неизменными, тогда может быть более уместным иметь защищенные геттеры/сеттеры, но эта ответственность может быть оставленный тем, кто создает «непрозрачные» слои в иерархии.
Пример: коллекция может содержать поле под названием «count». Базовая версия коллекции может хранить вещи таким образом, чтобы было удобно поддерживать поле, которое всегда содержит количество элементов, но производная версия может хранить вещи таким образом, чтобы это затруднило ситуацию. Имея поле под названием «count», базовый класс обещает своим прямым потомкам, что он будет поддерживать количество элементов в этом поле. Производный класс может хранить вещи по-другому, так что поле «count» не имеет смысла.Такой класс может затенять поле count с помощью свойства только для чтения; его потомки знали бы, что им нужно было прочитать свойство, а потомки первоначального класса знали бы, что они могут читать поле.
Важнейшим моментом является то, что защищенные вещи в классе создают контракт с прямыми потомками, и эти потомки могут решить, предоставлять ли подобный контракт суб-потомкам.
Приложение: единственное, что достигается путем добавления защищенных виртуальных геттеров и сеттеров, это возможность для производных классов изменять способ, которым код базового класса получает доступ к полям/свойствам. Иногда это необходимо, но чаще это создает проблемы. Например, если в коллекции часто могут быть удалены недавно добавленные элементы, производный класс может обернуть вещи так, чтобы последние несколько элементов были добавлены в небольшую «премиальную» коллекцию и переданы в основную коллекцию после добавления дополнительных дополнительных элементов. Код для основной коллекции будет ожидать свое собственное поле «count», чтобы указать, сколько элементов находится в основной коллекции. Если класс потомка переопределяет свойство count, чтобы включить его собственные элементы, основной код будет разорван. Класс потомков должен вместо этого указать поле count, чтобы его потомки увидели счет, который включает в себя бонусные элементы, но базовый класс по-прежнему будет видеть счет, который включает только его собственные элементы.
Почему, по вашему мнению, переменные-члены будут необходимы позже в производных классах? Для чего они нужны, и почему они должны быть выставлены? –