Основна ідея полягає в тому, що "поле" (змінна на рівні екземпляра), яке оголошується захищеним, ймовірно, більш видиме, ніж воно повинно бути, і менш "захищене", ніж ви могли б хотіти. У C / C ++ / Java / C # немає модифікатора доступу, який є еквівалентом "доступного лише дочірнім класам в межах однієї збірки", таким чином, ви надаєте можливість визначати своїх власних дітей, які можуть отримати доступ до поля у вашій збірці, але не дозволяти дітям, створеним в інших зборах, однакового доступу; C # має внутрішні та захищені модифікатори, але їх поєднання робить доступ "внутрішнім або захищеним", а не "внутрішнім і захищеним". Отже, поле, яке захищається, є доступним для будь-якої дитини, незалежно від того, написали ви цю дитину чи хтось інший. Таким чином, захищеними є відкриті двері для хакера.
Крім того, поля за їх визначенням майже не мають валідації, властивої їх зміні. у C # ви можете зробити одне лише повторне читання, що робить типи значень фактично постійними, а типи посилань неможливо повторно ініціалізувати (але все-таки дуже мінливі), але це про це. Як такі, навіть захищені, ваші діти (яким ви не можете довіряти) мають доступ до цього поля і можуть встановити його на щось недійсне, що робить стан об'єкта непослідовним (чого слід уникати).
Прийнятий спосіб роботи з полями - зробити їх приватними та отримати доступ до них із властивістю та / або методом отримання та налаштування. Якщо всім споживачам класу потрібна цінність, зробіть геттер (принаймні) публічним. Якщо це потрібно лише дітям, зробіть геттер захищеним.
Ще один підхід, який відповідає на питання, - це запитати себе; Чому код у дочірньому методі потребує можливості безпосередньо змінювати мої дані про стан? Що це говорить про цей код? Це аргумент "вертикальної відстані" на його обличчі. Якщо у дитини є код, який повинен безпосередньо змінювати стан батьків, то, можливо, цей код повинен належати в першу чергу батьків?