Zasięgi czy jak ktoś woli modyfikatory dostępu są ustalane wraz z deklaracją danego elementu klasy lub klasy.
Protected używasz w chwili w której potrzebujesz by z zewnątrz nie można było mieć dostępu do danego elementu. W przypadku właściwości możesz mieć dwa modyfikatory dostępu i jeden stawiasz przed właściwością a drugi przy get lub set. Wtedy ten get/set korzysta z tego modyfikatora dostepu a drugi element właściwości z tego przed deklaracją właściwości.
Protected możesz użyć jeżeli potrzebujesz na przykład stworzyć klasę bazową Zwierze i w niej mieć na przykład pole Waga. Każde zwierze ma wagę i może być ona potrzebna na przykład do obliczenia siły mięśni, czy też ile potrzebuje karmy. W takim wypadku używasz protected bo chcesz by pozostałe klasy, które odziedziczą miały dostęp do pola Waga. Jeżeli użyłbyś private i np stworzyl klasę Pies, która dziedziczy po Zwierze to wtedy nie mógłbyś posługiwać się tym polem. To samo oczywiscie dotyczy kazdego dowolnego elementu klasy.
Private jest ograniczajace do danej klasy i z zewnatrz obiektu nie ma sie do niej dostepu, podobnie w przypadku protected. Różnica jest taka ze wlaśnie dziedzicząc we wnetrzu klasy mozna uzywac tego elementu.
W przypadku C# modyfikatory dostepu są bezstratne lub jak ktos woli stałe. To znaczy protected bedzie protected nawet po dziesieciu dziedziczeniach. Wiem ze sa jezyki gdzie protected zmienia sie w private po dziedziczeniu i jest to chyba Java i C++. Ale sa tez jezyki w ktorych protected nie ma lub jego odpowiednika.
Jezeli chodzi o klasy abstrakcyjne to tak, private praktycznie tam nie wystepuje, a protected jest na wszystko co ma nie byc dostepne do zmiany w wewnatrz gotowego obiektu. Ja tu polecam sobie wyobrazic protected i private jako taka obudowe na sprzet elektroniczny, np telewizor. Telewizor sobie dziala a my mamy dostep tylko do jego pilota i przyciskow. Jakby sie moglo skonczyc korzystaniw z telewizora bez obudowy mozna sobie wyobrazic i jest to wlasnie szastanie public i internal.
Nie jest bledem uzywanie protected zamiast private dla kazdej klasy jaka sie tworzy chyba ze jest ona zapieczetowana ( nie mozna po niej dziedziczyc ) lub jest klasa statyczna. Kazda klasa moze byc odziedziczona by ja rozwijac a dzieki polimorfizmowi bedzie mozna korzystac z tej rozbudowanej formy w juz istniejacych klasach. Choc tez tu solid chce by korzystac z klas abstrakcyjnych jak i interfejsow, ale zycie pokazuje inaczej
To ze np Ty stwierdzasz ze klasa Uczen jest ta ostateczna nie oznacza ze w ramach calego projektu i jego rozwoju taka bedzie. Byc moze klasa Uczen bedzie potrzebowac Id ucznia i wtedy modyfikacja klasy samej Uczen jest bledem. Nalezy odziedziczyc po klasie Uczen np jako klasa UczenPlus i tam dodac. I teraz jakbys np chcial Id wyliczac np na podstawie PESEL a ten mial niedostepny bo zastosowano private to jestes zmuszony do modyfikacji klasy Uczen. Klasy z kolei powinny byc tak pisane by byly gotowe na rozbudowe, czyli dziedziczenie. Private w C# powinno być świętem dla pól i właściwości. Z kolei kazde metody powinny byc obarczane virtual jezeli masz tylko przypuszczenie ze moze ulec ona potrzebie zmian w ramach rozbudowy.
Ogólnie rzecz biorąc private jest w obrebie tylko danej klasy od jej pierwsze klamry do ostatniej. Bardzo nieintuicyjna rzecza dla przechodzacych z innych jezyków w których jest to realizowane inaczej jest to ze modyfikatory dostepu w C# sa obszarowe a nie per obiekt. Jezeli chcesz np stworzyc metode, ktora przyjmie jako parametr obiekt tej samej klasy co aktualnie pisana to mozesz miec dostep do elementow prywatnych takiego obiektu mimo, ze w innej klasie nie masz takiego dostepu. Np do konstruktora by stworzyc kopie jakiegos obiektu to wtedy nie potrzebujesz public czy internal, bo masz dostep do elementow private i protected.
C# ma tez nowe dwa modyfikatory dostepu, które sie zmieniaja i sa to protected private oraz protected internal. Kolejnosc tych polaczen jest obojetna. Roznia sie oni pomiedzy projektami w solucji.
Chyba na tym skończę bo temat modyfikatorów dostepu jest dość obszerny.