Die Grundidee ist, dass ein "Feld" (Variable auf Instanzebene), das als geschützt deklariert ist, wahrscheinlich sichtbarer als es sein muss und weniger "geschützt" ist, als Sie vielleicht möchten. In C / C ++ / Java / C # gibt es keinen Zugriffsmodifikator, der der Entsprechung von "Nur für untergeordnete Klassen in derselben Assembly zugänglich" entspricht. Auf diese Weise können Sie eigene untergeordnete Klassen definieren, die auf das Feld in Ihrer Assembly zugreifen können Kindern, die in anderen Baugruppen erstellt wurden, nicht den gleichen Zugriff gewähren; C # hat interne und geschützte Modifikatoren, aber wenn Sie diese kombinieren, wird der Zugriff "intern oder geschützt", nicht "intern und geschützt". Auf ein geschütztes Feld kann also jedes Kind zugreifen, unabhängig davon, ob Sie das Kind geschrieben haben oder es jemand anderes getan hat. Geschützt ist damit eine offene Tür für einen Hacker.
Außerdem haben Felder per Definition so gut wie keine Validierung, wenn sie geändert werden. In C # können Sie einen Readonly-Wert erstellen, wodurch Werttypen effektiv konstant und Referenztypen nicht neu initialisiert werden können (aber immer noch sehr wandelbar sind), aber das war es auch schon. Selbst geschützt haben Ihre Kinder (denen Sie nicht vertrauen können) Zugriff auf dieses Feld und können es auf einen ungültigen Wert setzen, wodurch der Zustand des Objekts inkonsistent wird (etwas, das vermieden werden muss).
Die akzeptierte Möglichkeit, mit Feldern zu arbeiten, besteht darin, sie privat zu machen und mit einer Eigenschaft und / oder einer Get- und Setter-Methode darauf zuzugreifen. Wenn alle Konsumenten der Klasse den Wert benötigen, machen Sie den Getter (zumindest) öffentlich. Wenn nur Kinder es brauchen, machen Sie den Getter geschützt.
Ein anderer Ansatz, der die Frage beantwortet, ist, sich selbst zu fragen. Warum muss Code in einer untergeordneten Methode die Möglichkeit haben, meine Statusdaten direkt zu ändern? Was sagt das über diesen Code aus? Das ist das "vertikale Distanz" -Argument. Wenn ein untergeordnetes Element Code enthält, der den Status des übergeordneten Elements direkt ändern muss, sollte dieser Code möglicherweise zunächst dem übergeordneten Element gehören.