Mieliście okazję zaznajomić się już z kilkoma rodzajami klas w "CSharpie". Było o klasie jako takiej, klasie potomnej, statycznej, zapieczętowanej, abstrakcyjnej, a teraz będzie o zagnieżdżonej. Klasa zagnieżdżona w języku C#, jej wygląd i tajniki obsługi. Taki jest temat niniejszego artykułu!
Tweet |
KLASA ZAGNIEŻDŻONA W JĘZYKU C#. JESZCZE JEDEN RODZAJ KLASY!
Gały będą teraz skierowane na klasę zagnieżdżoną (ang. "nested"), nazywaną także klasą wewnętrzną. Chodzi de facto o klasę "siedzącą" sobie w innej klasie! No i tyle! Tak ona się prezentuje jako przykład:
class MyOuterClass
{
class MyInnerClass
{
}
}
Zastosowanie zwykle kręci się wokół podkreślenia przynależności do innej klasy lub zapewnienia większego bezpieczeństwa przed instrukcjami z zewnątrz. Taka klasa zagnieżdżona może posiadać inny modyfikator dostępu niż klasa zewnętrzna np. zewnętrzna posiada modyfikator "public", a zagnieżdżona "private". Nie ma przeciwwskazań.
TO DOPIERO WIERZCHOŁEK GÓRY LODOWEJ
O wiele większe trudności sprawi rozumienie jaki ma to wpływ na kod z zewnątrz i na dane składowe. Żebyście wiedzieli, klasa zagnieżdżona w języku C# także może posiadać wszystko to, co ma prawo posiadać każda inna klasa. Pola, metody, właściwości publiczne, statyczne i każde inne. Wszystko to, co może mieć klasa "zwykła".
DOSTĘP BEZ OGRANICZEŃ
Zacznijmy od faktu, iż klasa zagnieżdżona w języku C# posiada dostęp do wszystkich składowych klas i to bez względu na jej modyfikator dostępu!!! Klasa wewnętrzna będzie mieć w dupie że coś jest prywatne albo publiczne, albo jeszcze jakieś inne. Aby nawiązać komunikację z klasą wewnętrzną, w konstruktorze trzeba dostarczyć referencję do instancji klasy zewnętrznej:
class MyOuterClass
{
public int x;
private int y;
class MyInnerClass(MyOuterClass moc)
{
moc.x = 6; // dozwolone
moc.y = 10; // dozwolone
}
}
I gra gitara.
RZECZ SIĘ DZIEJE W INSTANCJI...
W drugą stronę też można manewrować, tylko to już nie działa tak samo. Żeby wpływać na klasę wewnętrzną, na zewnątrz musi powstać instancja klasy, tak jak to robiliśmy poprzednio w stosunku do klas zewnętrznych:
Inside inside = new Inside();
Dokładnie tak. Teraz mamy wpływ na jej wszystkie składowe. I tu niespodzianka! Na zewnątrz już obowiązują modyfikatory dostępu tak jak zwykle. Czyli jeśli klasa zagnieżdżona w języku C# posiada coś prywatnego, to tego dostępu już nie będzie! Uważajcie na ten szczegół! Bardzo łatwo wpuszcza w maliny!
DOMYŚLNIE JESTEM NA WYŁĄCZNOŚĆ
A skoro o prywatności mowa, to domyślnie klasy wewnętrzne są prywatne (modyfikator "private"):
class MyInnerClass = private class MyInnerClass
Oznacza to, że dostęp z zewnątrz będzie dla kodu niemożliwy. Dlaczego domyślnie "private", a nie "internal", tak jak ma to miejsce przy klasie "zwykłej"? Bo w gruncie rzeczy jest to składowa klasy. A jak już wiecie, wszystkie składowe klasy domyślnie są prywatne.
KLASA WEWNĘTRZNA...NA ZEWNĄTRZ?
Tak, jest to możliwe. Stosujecie tylko inny zapis co do typu danych instancji. Zakładając, że występuje taki kod:
class MyOuterClass
{
class MyInnerClass
{
}
}
piszemy wówczas tak:
MyOuterClass.MyInnerClass mic = new MyOuterClass.MyInnerClass;
ale w środku klasy posiadającej tę zagnieżdżoną, stosujemy wtedy skrócony zapis jako że przynależy jedna do drugiej:
class MyOuterClass
{
class MyInnerClass
{
}
public MyOuterClass()
{
MyInnerClass mic = new MyInnerClass();
}
}
Nie zakręćcie się od tego wszystkiego. Kiedy utworzycie sobie taką instancję na zewnątrz, możecie korzystać ze wszystkich składowych jakimi dysponuje klasa zagnieżdżona w języku C#, o ile pozwala na to nałożony modyfikator dostępu.
![]() |
Klasa zagnieżdżona należy do innej klasy zewnętrznej. Ignoruje wszystkie modyfikatory dostępu i może skorzystać z dowolnej składowej, jednak w drugą stronę są już przestrzegane modyfikatory dostępu. W obu przypadkach potrzebna jest instancja dla nawiązania komunikacji.
Jeśli musicie, zróbcie sobie przy tym dłuższy przystanek bez cienia wyrzutów sumienia. Klasa zagnieżdżona w języku C# potrafi szokować samą sobą i nieprzestrzeganiem pewnych zasad, do których jesteśmy przyzwyczajeni.