Przestrzenie nazw. Tablice
Przegląd zagadnień
Zajęcia koncentrują się na ważnym zagadnieniu przestrzeni nazw, umożliwiających ograniczenie zasięgu ważności nazw w programie, co jest szczególnie ważną rzeczą przy licznych klasach języka, z których korzysta programista.
W drugiej części laboratorium omówiony zostanie najbardziej podstawowy typ kolekcji - tablica. Elementy te są w języku C# obiektami. Ponadto jest to jedyny typ kolekcji posiadający wbudowaną obsługę.
Zajęcia zakończą się samodzielnym napisaniem kilku aplikacji.
Przestrzenie nazw (1)
Cechą charakterystyczną języków obiektowych jest możliwość korzystania z wielu klas, często przygotowanych przez różnych programistów.
Sytuacja taka powoduje jednak pewne niebezpieczeństwo, bowiem język C# wymaga unikatowości nazw, a przy setkach czy tysiącach elementów niemożliwością jest zapamiętanie wszystkich - któryś z tworzonych przez programistę elementów prędzej czy później zostanie nazwany w taki sam sposób jak inny.
Rozwiązaniem problemu jest stosowanie przestrzeni nazw - ograniczających zasięg ważności nazw.
Przestrzenie nazw (2)
Zamiast pisać w całym programie na przykład System.Console.WriteLine, możemy ułatwić sobie zadanie, wpisując na początku kodu programu using System;. Pozwoli to na korzystanie w aplikacji ze składni Console.WriteLine.
Należy jednak wystrzegać nadużywania dyrektywy using. Wyobraźmy sobie sytuację, w której umieścimy w nagłówku programu po dyrektywie using nazwy klas zawierających element o takiej samej nazwie. Skąd program ma wiedzieć, którego z nich chcemy w danym momencie użyć?
Przestrzenie nazw pomagają nam także w doprecyzowaniu kontekstu - jak chociażby jest to w przypadku opisanym na slajdzie - kiedy firma szuka doświadczonego programisty. Można jeszcze uszczegółowić - na przykład jeśli szukamy osoby piszącej w języku C#, będzie to obiekt.cSharp.programista.
Operatorem, który w języku C# pozwala na dostęp do metod i danych klasy, jednocześnie określając zasięg ważności nazw jest operator kropki.
Przestrzenie nazw - przykład
W powyższym kodzie korzystamy z zagnieżdżonych przestrzeni nazw. W przestrzeni nazw PrzestrzenZewnetrzna znajdują się przestrzeń nazw PrzestrzenWewnetrzna z klasą Owoc zawierającą metodę Jabłko(), a także klasa PrzestrzenWywolujaca.
Po uruchomieniu programu wykona się metoda Main() w klasie PrzestrzenWywolujaca, w efekcie czego zobaczymy na ekranie komunikat „Jabłko - element wywołany w innej przestrzeni nazw”.
Należy zwrócić uwagę na linię zawierającą odniesienie do metody Jabłko() - gdybyśmy pominęli któryś z elementów, niemożliwe byłoby jej wywołanie.
Wywołanie tej samej metody spoza klasy PrzestrzenZewnetrzna wymagałoby dodatkowo umieszczenia przed PrzestrzenWewnetrzna.Owoc.Jablko() jej nazwy.
Przestrzenie nazw - podsumowanie
Przestrzenie nazw pomagają w podziale hierarchii obiektów, dzięki czemu stosunkowo łatwo można konstruować model wycinka rzeczywistości dla potrzeb programu.
Dzięki dyrektywie using mamy możliwość umieszczenia w nagłówku programu najczęściej używanych klas. Pozwoli to skrócić zapis, jednak nadużywanie tej opcji może zaowocować zmniejszoną czytelnością kodu.
Należy zwracać uwagę, czy w klasach umieszczonych na początku programu po dyrektywie using występują unikatowe nazwy - pozwoli to zaoszczędzić czas na rozwiązywanie potencjalnych problemów spowodowanych przez wielokrotne użycie elementów z różnych klas o tych samych nazwach.
Tablice
Tablica jest najprostszym przykładem kolekcji złożonej z tych samych elementów. Posiada ona wbudowany mechanizm indeksowania, dzięki czemu możliwe jest natychmiastowe uzyskanie dostępu do dowolnego jej elementu.
Należy pamiętać o tym, że pierwszy element tablicy ma numer 0, więc na przykład odwołanie się do elementu o numerze 7 w siedmioelementowej tablicy spowoduje błąd. Ostatni element takiej tablicy ma numer 6.
Tablice - przykład obiektów
Mimo zwyczajnie wyglądającej deklaracji, tworząc tablicę w rzeczywistości powołujemy do życia obiekt typu System.Array lub pochodnego od niego. Rozwiązanie takie umożliwia udostępnianie użytecznych metod i właściwości razem z tablicą.
Tablice są jedynym typem kolekcji posiadającym wbudowaną obsługę w języku C#. Za pomocą metod i właściwości klasy System.Array możemy na przykład sprawdzić liczbę elementów tablicy (właściwość Length) czy znaleźć miejsce ostatniego wystąpienia danej wartości w tablicy jednowymiarowej (metoda LastIndexOf()).
Jest to rozbudowana klasa, z którą warto się zapoznać w wolnej chwili.
Tablice - przykład
Przykład rozpoczyna się od definicji klasy Samochod, udostępniającej konstruktor z parametrem w postaci liczby całkowitej. Klasa przesłania odziedziczoną po klasie Object metodę ToString(), wyświetlającą wartość Lp dla obiektu Samochod.
Metoda w klasie Tester deklaruje i tworzy egzemplarze dwóch tablic, ustawiając wartości tablicy elementów całkowitych na 0. W tablicy obiektów Samochod ustawiamy wartości elementów przy pomocy instrukcji for.
Warto zwrócić uwagę na użycie właściwości Length, zwracającej liczbę elementów tablicy.
Zamiast instrukcji for możliwe jest użycie instrukcji foreach, która przechodzi po kolei wszystkich elementach kolekcji.
Tablice - dalsze informacje
W poprzednim przykładzie w miejsce pętli for można było użyć instrukcji przygotowanej specjalnie z myślą o przechodzeniu po elementach kolekcji - foreach.
Zamiast zapisu
for (int i = 0; i<TablicaLp.Length; i++) { instrukcje }
mielibyśmy wówczas
foreach ( Samochod s in TablicaLp) { instrukcje }
Istnieje możliwość inicjalizacji elementów tablicy w czasie tworzenia egzemplarza. W większości wypadków wybór składni nie robi różnicy, dlatego warto używać krótszej formy.
Są jednak sytuacje, w których kompilator ma problem z określeniem typu elementów tablicy - wówczas pozostaje dłuższa forma.
Tablice wielowymiarowe (1)
W języku C# mamy dwie możliwości wykorzystania tablic wielowymiarowych. Pierwszą z nich są tablice prostokątne. Po podaniu typu w nawiasie kwadratowym wymieniamy wówczas po przecinku kolejne wymiary (są to w pewnym sensie odpowiedniki wiersza i kolumny z przypadku tablicy prostokątnej dwuwymiarowej).
W przypadku deklaracji powiązanej z utworzeniem egzemplarza klasy możemy skorzystać z opisanej składni. W załączonym fragmencie kodu utworzyliśmy trójwymiarową tablicę liczb całkowitych o wymiarach 2x3x5.
Ostatni fragment kodu na slajdzie ilustruje mechanizm bezpośredniego inicjalizowania elementów tablicy.
Tablice wielowymiarowe (2)
Drugim typem tablic wielowymiarowych są tablice nieregularne - poszczególne ich rzędy nie muszą być tej samej długości.
Tworząc tablicę wielowymiarową tego rodzaju musimy podać liczbę rzędów każdej tablicy, co wykonujemy podając każdy wymiar w osobnym kwadratowym nawiasie po uprzednim określeniu typu.
Kwestia dostępu do elementów tablicy została rozwiązana poprzez podawanie po nazwie tablicy w nawiasach kwadratowych kolejno numeru tablicy i pozycji elementu w tej tablicy (należy pamiętać, że oba liczniki zaczynają się od zera!).
Podsumowanie
Przestrzenie nazw są mechanizmem, który pozwala programiście nie przejmować się znajomością nazw wszystkich elementów wszystkich klas - byłaby to Syzyfowa praca w obliczu faktu, że nieustannie ich przybywa.
Zamiast tego stosuje się ograniczenie zakresu ważności nazwy.
Tablica jest najprostszym przykładem kolekcji elementów tego samego typu. Jest to zarazem jedyna kolekcja posiadająca wbudowaną obsługę w języku C#.
Warto pamiętać, że język C# dysponuje specyficznymi rodzajami tablic wielowymiarowych - są to aż dwa typy - tablice prostokątne oraz tablice nieregularne.
Pytania sprawdzające
Pytania kontrolne dla studentów:
Jaka jest rola operatora kropki w przestrzeniach nazw?
Do czego służy instrukcja foreach?
Omów rodzaje tablic.
Laboratorium
Przygotuj program, który będzie potrafił odróżnić deskę do prasowania od deski do krojenia i deski kreślarskiej.
Zaprojektuj i napisz aplikację, która będzie wyświetlać stopnie całej klasy z matematyki.
Znajdź opis metod statycznych Sort() oraz Reverse() w klasie System.Array, a następnie zmodyfikuj napisany w punkcie drugim program tak, by dodatkowo wyświetlał numery w dzienniku według średniej ocen w porządku rosnącym i malejącym.
L
L