• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Visual Basic .NET. Księga eksperta
 

Visual Basic .NET. Księga eksperta

on

  • 1,450 views

Visual Basic przeszedł generalny remont. Istnieje wiele powodów, dla których programiści Visual Basica 6 powinni przesiąść się na nowy Visual Basic .NET. Należy do nich zaliczyć chociażby ...

Visual Basic przeszedł generalny remont. Istnieje wiele powodów, dla których programiści Visual Basica 6 powinni przesiąść się na nowy Visual Basic .NET. Należy do nich zaliczyć chociażby formularze Web, możliwość tworzenia aplikacji i usług WWW, strukturalną obsługę wyjątków, prawdziwe programowanie zorientowane obiektowo czy też wielowątkowość.

"Visual Basic .NET. Księga eksperta" zawiera dokładne omówienie nowego języka Visual Basic .NET, zunifikowanego środowiska programowania Visual Studio IDE, programowania formularzy WWW, ADO.NET, usługi WWW, GDI+ i wiele innych.

Visual Studio .NET jest środowiskiem bardzo rozbudowanym i potężnym. Aby w pełni je wykorzystać, poznasz także sposoby tworzenia makr oraz znajdziesz omówienie modelu automatyzacji służącego do indywidualizacji zadań i interfejsu IDE w Visual Studio. Książka zawiera wiele przykładów wziętych z praktyki programistycznej.

Książka omawia:

* Środowisko programistyczne Visual Studio, korzystanie z SourceSafe
* Język Visual Basic .NET, programowanie zorientowane obiektowo w VB .NET
* Rozszerzanie środowiska programistycznego za pomocą makr
* Zaawansowane programowanie w VB .NET: refleksje, przeciążanie, programowane oparte na zdarzeniach, polimorfizm, definiowanie atrybutów
* Tworzenie interfejsu użytkownika (aplikacje konsolowe, aplikacje z interfejsem Windows)
* Pisanie aplikacji wielowątkowych
* Uruchamianie usług WWW (Web Services)

"Visual Basic .NET. Księga eksperta" jest doskonałym podręcznikiem dla wszystkich osób, dla których osiągnięcie wysokiej sprawności w posługiwaniu się językiem Visual Basic stanowi podstawę kariery programistycznej. Niezależnie, od tego, czy używałeś poprzedniej wersji tego języka, czy też nie: jeśli chcesz stać się ekspertem Visual Basica, trzymasz w ręku odpowiednią książkę.

Statistics

Views

Total Views
1,450
Views on SlideShare
1,450
Embed Views
0

Actions

Likes
0
Downloads
9
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Visual Basic .NET. Księga eksperta Visual Basic .NET. Księga eksperta Document Transcript

    • IDZ DO PRZYK£ADOWY ROZDZIA£ SPIS TRE CI Visual Basic .NET. Ksiêga eksperta KATALOG KSI¥¯EK Autor: Paul Kimmel KATALOG ONLINE T³umaczenie: Krzysztof Jurczyk, Marek Pa³czyñski ISBN: 83-7197-771-9 ZAMÓW DRUKOWANY KATALOG Tytu³ orygina³u: Visual Basic .NET Unleashed Format: B5, stron: 682 Przyk³ady na ftp: 3044 kB TWÓJ KOSZYK DODAJ DO KOSZYKA Visual Basic przeszed³ generalny remont. Istnieje wiele powodów, dla których programi ci Visual Basica 6 powinni przesi¹ æ siê na nowy Visual Basic .NET. Nale¿y do nich zaliczyæ chocia¿by formularze Web, mo¿liwo æ tworzenia aplikacji CENNIK I INFORMACJE i us³ug WWW, strukturaln¹ obs³ugê wyj¹tków, prawdziwe programowanie zorientowane obiektowo czy te¿ wielow¹tkowo æ. ZAMÓW INFORMACJE „Visual Basic .NET. Ksiêga eksperta” zawiera dok³adne omówienie nowego jêzyka O NOWO CIACH Visual Basic .NET, zunifikowanego rodowiska programowania Visual Studio IDE, programowania formularzy WWW, ADO.NET, us³ugi WWW, GDI+ i wiele innych. ZAMÓW CENNIK Visual Studio .NET jest rodowiskiem bardzo rozbudowanym i potê¿nym. Aby w pe³ni je wykorzystaæ, poznasz tak¿e sposoby tworzenia makr oraz znajdziesz omówienie modelu automatyzacji s³u¿¹cego do indywidualizacji zadañ i interfejsu IDE w Visual CZYTELNIA Studio. Ksi¹¿ka zawiera wiele przyk³adów wziêtych z praktyki programistycznej. Ksi¹¿ka omawia: FRAGMENTY KSI¥¯EK ONLINE • rodowisko programistyczne Visual Studio, korzystanie z SourceSafe • Jêzyk Visual Basic .NET, programowanie zorientowane obiektowo w VB .NET • Rozszerzanie rodowiska programistycznego za pomoc¹ makr • Zaawansowane programowanie w VB .NET: refleksje, przeci¹¿anie, programowane oparte na zdarzeniach, polimorfizm, definiowanie atrybutów • Tworzenie interfejsu u¿ytkownika (aplikacje konsolowe, aplikacje z interfejsem Windows) • Pisanie aplikacji wielow¹tkowych • Uruchamianie us³ug WWW (Web Services) „Visual Basic .NET. Ksiêga eksperta” jest doskona³ym podrêcznikiem dla wszystkich osób, dla których osi¹gniêcie wysokiej sprawno ci w pos³ugiwaniu siê jêzykiem Visual Wydawnictwo Helion Basic stanowi podstawê kariery programistycznej. Niezale¿nie, od tego, czy u¿ywa³e ul. Chopina 6 poprzedniej wersji tego jêzyka, czy te¿ nie: je li chcesz staæ siê ekspertem Visual 44-100 Gliwice Basica, trzymasz w rêku odpowiedni¹ ksi¹¿kê. tel. (32)230-98-63 e-mail: helion@helion.pl
    • 5RKU VTG EK 1 #WVQTG  9UVúR %ú è + 9RTQYCFGPKG FQ 8KUWCN $CUKE 0'6  4QFKC  7LGFPQNKEQPG TQFQYKUMQ RTCE[ 8KUWCN 5VWFKQ Profile u ytkownika.................................................................................................................. 30 Tworzenie projektu .................................................................................................................. 31 Pliki i katalogi projektu ....................................................................................................... 31 Dodawanie projektu do kontroli kodu źródłowego ................................................................. 33 Kompilacja projektów............................................................................................................... 35 Korzystanie z mened era konfiguracji................................................................................... 36 Właściwości wspólne .......................................................................................................... 36 Opcje konfiguracyjne .......................................................................................................... 38 Debug Build ....................................................................................................................... 38 Release Build ..................................................................................................................... 38 Kompilacje typu Command-Line oraz korzystanie z Make File ............................................... 39 Organizacja kodu źródłowego formularza ................................................................................... 39 Przełączanie się pomiędzy widokiem kodu a widokiem obiektów............................................ 42 Przestrzenie nazw ............................................................................................................... 43 Skracanie kodu ................................................................................................................... 44 Dyrektywa #Region ............................................................................................................ 45 Edytowanie kodu i cechy ułatwiające tworzenie dokumentacji ................................................ 45 Konfiguracja opcji IDE ............................................................................................................. 48 Opcje środowiska ............................................................................................................... 49 Opcje kontroli kodu źródłowego........................................................................................... 49 Opcje edytora tekstu ........................................................................................................... 49 Opcje projektanta formularzy (Windows Forms Designer)...................................................... 50 Opcje analizatora ................................................................................................................ 50 Opcje narzędzi bazy danych ................................................................................................ 50 Opcje debugowania............................................................................................................. 50 Opcje projektanta HTML .................................................................................................... 51 Opcje projektu.................................................................................................................... 51 Opcje projektanta XML ...................................................................................................... 51 Proces debugowania w nowym IDE ........................................................................................... 51 Podstawowe klawisze skrótów podczas debugowania............................................................. 52 Strukturalna obsługa wyjątków ............................................................................................ 53 Przegląd Szablonów Projektów.................................................................................................. 53 Windows Application.......................................................................................................... 53 Class Library...................................................................................................................... 54
    • 6 Visual Basic .NET. Księga eksperta Windows Control Library .................................................................................................... 55 ASP.NET Web Applications ................................................................................................ 55 ASP.NET Web Service ....................................................................................................... 57 Web Control Library ........................................................................................................... 58 Empty Project .................................................................................................................... 58 Empty Web Project............................................................................................................. 58 New Project in Existing Folder............................................................................................. 58 Projekty w wersji Enterprise ................................................................................................ 58 Technologia IntelliSense ........................................................................................................... 60 Składowe klas..................................................................................................................... 60 Informacja o parametrach.................................................................................................... 60 Szybka podpowiedź ............................................................................................................ 60 Dokańczanie wyrazów ........................................................................................................ 60 Cechy IntelliSense specyficzne dla VB ................................................................................. 61 Korzystanie z widoków............................................................................................................. 61 Solution Explorer................................................................................................................ 61 Class View......................................................................................................................... 62 Server Explorer................................................................................................................... 62 Resource View ................................................................................................................... 63 Properties Window ............................................................................................................. 63 Toolbox ............................................................................................................................. 63 Pendind Check-ins .............................................................................................................. 63 Web Browser ..................................................................................................................... 63 Inne okna........................................................................................................................... 64 Dokumentacja.......................................................................................................................... 67 Podsumowanie......................................................................................................................... 67 4QFKC  %CU PC OKCP[  Rozszerzenia plików ................................................................................................................. 69 Grupy Visual Basic jako rozwiązania.................................................................................... 69 Nowe rozszerzenia plików źródłowych ................................................................................. 69 Przestrzenie nazw..................................................................................................................... 71 Referencje ............................................................................................................................... 72 Dyrektywy Option.................................................................................................................... 72 Option Explicit ................................................................................................................... 72 Option Compare ................................................................................................................. 74 Option Strict....................................................................................................................... 74 Moduł Option Private.......................................................................................................... 75 Option Base ....................................................................................................................... 76 Typy danych............................................................................................................................ 76 Typy Object ....................................................................................................................... 77 Typy całkowite ................................................................................................................... 80 Typy niecałkowite............................................................................................................... 81 Typ Char ........................................................................................................................... 85 Typ String.......................................................................................................................... 86 Typ Boolean....................................................................................................................... 89 Typ DateTime .................................................................................................................... 91 Deklaracje zmiennych............................................................................................................... 94 Deklarowanie i inicjowanie pojedynczej zmiennej ................................................................. 95 Deklaracje wielu zmiennych jednocześnie............................................................................. 96
    • Spis treści 7 Inicjowanie wielu zmiennych jednocześnie ........................................................................... 97 Definiowanie stałych........................................................................................................... 98 Tworzenie egzemplarzy obiektów ........................................................................................ 98 Listy inicjujące zmienne ...................................................................................................... 99 Operatory ................................................................................................................................ 99 Funkcje konwersji typów ........................................................................................................ 101 Zmiany zasięgu zmiennych w VB .NET................................................................................... 103 Instrukcje sterowania pracą programu ...................................................................................... 103 Tablice i kolekcje ................................................................................................................... 104 Tablice o określonych granicach......................................................................................... 105 Tablice N-wymiarowe ....................................................................................................... 105 Modyfikacja rozmiarów tablic............................................................................................ 106 Zwracanie tablic przez funkcje........................................................................................... 106 Tablice jako podklasy System.Array................................................................................... 107 Abstrakcyjne typy danych ................................................................................................. 107 Strukturalna obsługa wyjątków ................................................................................................ 109 Korzystanie ze słów zastrze onych w Visual Basic .NET........................................................... 110 Kompatybilność pomiędzy aplikacjami VB6 a VB .NET ........................................................... 110 Microsoft.VisualBasic ....................................................................................................... 110 Elementy programowania VB6 zmienione w Visual Basic .NET........................................... 111 Podsumowanie....................................................................................................................... 111 4QFKC  2QFUVCY[ RTQITCOQYCPKC Y 8KUWCN $CUKE 0'6 Deklarowanie i inicjowanie zmiennych..................................................................................... 113 Inicjowanie zmiennych...................................................................................................... 114 Deklarowanie i inicjowanie zmiennych w pojedynczej instrukcji........................................... 116 Deklarowanie zmiennych tu przed ich pierwszym u yciem ................................................. 116 Deklarowanie zmiennych o jak najmniejszym zasięgu.......................................................... 116 Korzystanie z refaktoringu: zamiana zmiennych tymczasowych na kwerendy ........................ 117 Praca z zasięgiem blokowym ................................................................................................... 119 Zmienne statyczne.................................................................................................................. 120 U ywanie zmiennych statycznych ...................................................................................... 120 Zmienne statyczne a pamięć .............................................................................................. 121 Korzystanie z tablic ................................................................................................................ 121 Tablice są instancjami klasy System.Array .......................................................................... 121 Deklarowanie tablic .......................................................................................................... 122 Korzystanie z metod tablicowych ....................................................................................... 122 Tablice wielowymiarowe................................................................................................... 123 Praca z abstrakcyjnymi typami danych ..................................................................................... 125 Składowe klasy ArrayList.................................................................................................. 126 U ywanie ArrayList .......................................................................................................... 127 HashTable........................................................................................................................ 128 SortedList ........................................................................................................................ 129 Queue.............................................................................................................................. 130 Podsumowanie Abstrakcyjnych Typów Danych .................................................................. 130 Przesłanianie zmiennych ......................................................................................................... 131 Funkcje i podprogramy ........................................................................................................... 132 Definiowanie struktur ............................................................................................................. 132
    • 8 Visual Basic .NET. Księga eksperta U ywanie obiektów ................................................................................................................ 132 Co to jest konstruktor? ...................................................................................................... 133 Konstruktory sparametryzowane ........................................................................................ 134 Destruktory ...................................................................................................................... 134 Obsługa wyjątków.................................................................................................................. 135 Try...Catch....................................................................................................................... 135 Try...Finally ..................................................................................................................... 139 Podsumowanie....................................................................................................................... 140 4QFKC  /CMTC K TQUGTGPKC 8KUWCN 5VWFKQ  Automatyzacja zadań powtarzających się ................................................................................. 142 Przykład: nagrywanie makra .............................................................................................. 142 Podgląd zarejestrowanego makra........................................................................................ 143 Edycja makra tymczasowego ............................................................................................. 144 Uruchamianie makra ......................................................................................................... 148 Przypisywanie klawiszy skrótu do makra ............................................................................ 149 Dodawanie klawisza makra do paska narzędziowego ........................................................... 149 Korzystanie z Eksploratora Makr ............................................................................................. 151 Eksport makra........................................................................................................................ 151 Makra włączające i wyłączające pułapki ............................................................................. 151 Wysyłanie informacji do okna wyjściowego Output............................................................. 153 Eksportowanie modułów makra ......................................................................................... 155 Importowanie modułów makra........................................................................................... 155 Korzystanie z Macros IDE ...................................................................................................... 155 Bezpieczeństwo makr........................................................................................................ 156 Współdzielenie makr......................................................................................................... 156 Tworzenie projektu makra ...................................................................................................... 156 Obsługa Visual Studio poprzez okno Command........................................................................ 158 Odpowiadanie na zdarzenia IDE .............................................................................................. 158 Dostosowanie Visual Studio do własnych wymagań .................................................................. 160 Ogólny opis Extensibility Object Model.............................................................................. 161 Ogólny opis Project-Neutral Extensibility Object Model....................................................... 165 Tworzenie przystawek ............................................................................................................ 167 Tworzenie projektu przystawki .......................................................................................... 168 Rejestracja przystawek...................................................................................................... 172 Dodawanie zachowań do przystawki .................................................................................. 173 Tworzenie kreatorów.............................................................................................................. 174 Tworzenie pliku uruchomieniowego kreatora ...................................................................... 176 Rejestracja biblioteki klas kreatora ..................................................................................... 176 Testowanie kreatora.......................................................................................................... 176 Program Integracji Visual Studio ............................................................................................. 177 Podsumowanie....................................................................................................................... 178 4QFKC  2TQEGFWT[ HWPMELG K UVTWMVWT[  Pisanie procedur..................................................................................................................... 179 Pisanie procedur ............................................................................................................... 180 Pisanie funkcji .................................................................................................................. 182 Definiowanie argumentów procedury ....................................................................................... 185 Domyślne przekazywanie parametrów ................................................................................ 186 Korzystanie z parametrów opcjonalnych ............................................................................. 190
    • Spis treści 9 Definiowanie argumentów ParamArray .............................................................................. 193 Redukowanie liczby parametrów........................................................................................ 194 Praca z rekurencją .................................................................................................................. 199 Definiowanie procedur rekurencyjnych............................................................................... 199 Zamiana rekurencji na algorytm nierekurencyjny................................................................. 199 Definiowanie struktur ............................................................................................................. 200 Definiowanie pól i właściwości .......................................................................................... 201 Dodawanie metod do struktur ............................................................................................ 202 Implementowanie konstruktorów ....................................................................................... 203 Definiowanie zdarzeń strukturalnych .................................................................................. 205 Deklarowanie zmiennych w strukturze................................................................................ 207 Ukrywanie informacji........................................................................................................ 208 Argumenty struktur i typy zwracane ................................................................................... 208 Cechy niedostępne dla struktur........................................................................................... 208 Korzystanie z typów wyliczeniowych....................................................................................... 209 Podsumowanie....................................................................................................................... 210 %ú è ++ <CCYCPUQYCPG RTQITCOQYCPKG QTKGPVQYCPG QDKGMVQYQ   4QFKC  4GHNGMULG Przestrzeń nazw Reflection...................................................................................................... 213 Pakiety ............................................................................................................................ 214 Manifest jako źródło informacji o zasobach......................................................................... 216 Obiekt modułu.................................................................................................................. 216 Obiekt File ....................................................................................................................... 219 Właściwość Location ........................................................................................................ 221 Właściwość EntryPoint ..................................................................................................... 221 Właściwość GlobalAssemblyCache .................................................................................... 221 Type................................................................................................................................ 221 Wiązania.......................................................................................................................... 222 Klasa MethodInfo ............................................................................................................. 227 Klasa ParameterInfo ......................................................................................................... 228 Klasa FieldInfo ................................................................................................................. 228 Klasa PropertyInfo............................................................................................................ 228 Klasa EventInfo................................................................................................................ 228 Tworzenie typów w trakcie działania aplikacji z wykorzystaniem refleksji .................................. 229 Inne przypadki korzystania z refleksji....................................................................................... 232 Lokalizacja ............................................................................................................................ 233 Podsumowanie....................................................................................................................... 233 4QFKC  6YQTGPKG MNCU Definiowanie klas................................................................................................................... 235 U ywanie specyfikatorów dostępu do klas .......................................................................... 237 Hermetyzacja i ukrywanie informacji ....................................................................................... 239 Specyfikatory dostępu ....................................................................................................... 240 Praca z zasięgiem.............................................................................................................. 240 Dodawanie pól i właściwości................................................................................................... 240 Hermetyzacja i właściwości ............................................................................................... 242 Definiowanie właściwości indeksowanych .......................................................................... 243 Korzystanie z modyfikatorów właściwości .......................................................................... 250
    • 10 Visual Basic .NET. Księga eksperta Definiowanie właściwości współdzielonych ........................................................................ 253 Dodawanie atrybutów właściwości ..................................................................................... 253 Dodawanie metod do klas ....................................................................................................... 254 Implementowanie konstruktorów i destruktorów.................................................................. 256 Dodawanie funkcji i procedur do metod.............................................................................. 260 Korzystanie z modyfikatorów metod .................................................................................. 263 Korzystanie ze specyfikatorów dostępu............................................................................... 265 Dodawanie zdarzeń do klas ..................................................................................................... 266 Definiowanie klas zagnie d onych........................................................................................... 267 Zrozumienie celu korzystania z klas zagnie d onych ........................................................... 271 Definiowanie klasy Signal ................................................................................................. 272 Definiowanie abstrakcyjnej klasy bazowej Light.................................................................. 276 Implementowanie świateł sygnalizacji ................................................................................ 276 Podsumowanie programu TrafficLight................................................................................ 277 Tworzenie egzemplarzy klas.................................................................................................... 277 Podsumowanie....................................................................................................................... 278 4QFKC  &QFCYCPKG FCTG  Rozumienie zdarzeń i procedur ich obsługi ............................................................................... 279 Podstawowa delegacja: EventHandler................................................................................. 281 Dołączanie wielu zdarzeń do jednej procedury obsługi ......................................................... 288 Tworzenie procedur obsługi zdarzeń w edytorze kodu ............................................................... 290 Pisanie procedur obsługi zdarzeń w edytorze kodu .............................................................. 293 Przypisywanie procedur obsługi zdarzeń w trakcie pracy aplikacji......................................... 294 Tworzenie procedur obsługi zdarzeń w trakcie pracy aplikacji .................................................... 294 Tworzenie procedur obsługi zdarzeń w WebForms Designer ...................................................... 296 Deklarowanie i wywoływanie zdarzeń...................................................................................... 296 Deklarowanie zdarzeń ....................................................................................................... 298 Generowanie zdarzeń ........................................................................................................ 299 Implementowanie procedur obsługi zdarzeń klasy................................................................ 300 Implementowanie procedur obsługi zdarzeń współdzielonych............................................... 300 Implementowanie procedur obsługi zdarzeń modułowych .................................................... 300 Implementowanie procedur obsługi zdarzeń struktury .......................................................... 302 Niedostępne właściwości zdarzeń....................................................................................... 303 Podsumowanie....................................................................................................................... 303 4QFKC  &GNGICELG U ywanie delegacji EventHandler............................................................................................ 306 Korzystanie z argumentów obiektu EventHandler ................................................................ 306 Korzystanie z argumentu EventHandler System.EventArgs................................................... 315 Przegląd składowych delegacji ................................................................................................ 315 Definiowanie delegacji............................................................................................................ 317 Deklarowanie procedur odpowiadających sygnaturom delegacji............................................ 317 Inicjowanie delegacji......................................................................................................... 318 Cel stosowania delegacji.................................................................................................... 318 Przekazywanie delegacji jako argumentów ............................................................................... 319 Przegląd algorytmów sortowania i opis działania aplikacji.................................................... 320 Algorytmy sortowania ....................................................................................................... 321 Analiza działania aplikacji SortAlgorithms.......................................................................... 321 Alternatywa dla typów proceduralnych ............................................................................... 326
    • Spis treści 11 Delegacje grupowe ................................................................................................................. 327 Metoda Combine .............................................................................................................. 329 Korzystanie z delegacji grupowych..................................................................................... 329 Korzystanie z delegacji poza granicami projektu ....................................................................... 330 Podsumowanie....................................................................................................................... 333 4QFKC  &KGFKEGPKG K RQNKOQTHKO Podstawy dziedziczenia........................................................................................................... 335 Co to jest dziedziczenie? ......................................................................................................... 336 Podstawowa składnia dziedziczenia.................................................................................... 337 Dziedziczenie w przykładach ............................................................................................. 338 Implementowanie właściwości, zdarzeń i metod w edytorze kodu......................................... 339 Dziedziczenie pojedyncze a dziedziczenie wielokrotne......................................................... 342 Definiowanie klas, które muszą być dziedziczone...................................................................... 342 Przykład wirtualnej klasy abstrakcyjnej .............................................................................. 343 Definiowanie klas, które nie mogą być dziedziczone.................................................................. 345 Polimorfizm........................................................................................................................... 346 Trzy rodzaje polimorfizmu ................................................................................................ 348 Wywoływanie metod dziedziczonych ................................................................................. 350 Przesłanianie metody klasy nadrzędnej ............................................................................... 350 Dynamiczne rzutowanie typów ................................................................................................ 352 Definiowanie interfejsów ........................................................................................................ 354 Interfejsy a klasy .............................................................................................................. 354 Definiowanie interfejsu ..................................................................................................... 355 Podsumowanie....................................................................................................................... 357 4QFKC  5M CFQYG YURÎ FKGNQPG Deklarowanie pól współdzielonych .......................................................................................... 359 Definiowanie właściwości współdzielonych.............................................................................. 360 U ywanie metod współdzielonych ........................................................................................... 364 Definiowanie konstruktorów współdzielonych .......................................................................... 369 Konstruktory współdzielone i singletony............................................................................. 369 Przykład konstruktora współdzielonego .............................................................................. 370 Implementowanie metod fabrycznych ...................................................................................... 375 Przecią anie składowych współdzielonych ............................................................................... 378 Generowanie zdarzeń współdzielonych .................................................................................... 380 Podsumowanie....................................................................................................................... 382 4QFKC  &GHKPKQYCPKG CVT[DWVÎY  Rola atrybutów....................................................................................................................... 384 Czym są metadane? .......................................................................................................... 384 Nazwy atrybutów ............................................................................................................. 390 Elementy opisywane przez atrybuty.................................................................................... 391 Opisywanie pakietu........................................................................................................... 391 Oznaczanie typów i składowych .............................................................................................. 393 Dodawanie atrybutów typu ................................................................................................ 393 Dodawanie atrybutów metod ............................................................................................. 396 Dodawanie atrybutów pól i własności ................................................................................. 399 Przeglądanie atrybutów za pomocą deasemblera MSIL.............................................................. 403 Pozyskiwanie atrybutów za pomocą refleksji ............................................................................ 403
    • 12 Visual Basic .NET. Księga eksperta Tworzenie atrybutów u ytkownika .......................................................................................... 405 Implementacja HelpAttribute ............................................................................................. 405 Deklarowanie klasy atrybutu.............................................................................................. 405 Określanie zasad u ycia atrybutu — AttributeUsage ............................................................ 406 Dziedziczenie z System.Attribute ....................................................................................... 407 Implementowanie konstruktora .......................................................................................... 407 Dodawanie nazwanych argumentów ................................................................................... 408 Atrybutu komponentów .......................................................................................................... 408 Atrybuty współpracy z COM................................................................................................... 409 Podsumowanie....................................................................................................................... 409 %ú è +++ 2TQLGMV KPVGTHGLUW W [VMQYPKMC   4QFKC  #RNKMCELC MQPUQNQYC Podstawy aplikacji konsolowych.............................................................................................. 413 Procedura Sub Main implementowana w module ................................................................. 414 Procedura Sub Main implementowana w klasie ................................................................... 415 Pozyskiwanie argumentów wierszy poleceń ........................................................................ 416 Klasa Console ........................................................................................................................ 420 Odczyt i zapis w standardowych urządzeniach wejścia-wyjścia............................................. 421 Zapis do urządzenia informacji o błędach............................................................................ 423 Zmiana urządzenia informacji o błędach ............................................................................. 424 Implementacja programu FileSort ............................................................................................ 425 Stosowanie TextReader ..................................................................................................... 426 Stosowanie TextWriter ...................................................................................................... 430 Pliki tymczasowe.............................................................................................................. 430 Stosowanie interfejsu IEnumerator ..................................................................................... 431 Sortowanie w ArrayList..................................................................................................... 432 Implementowanie interfejsu IComparer .............................................................................. 432 Przestrzenie nazw aplikacji konsolowych.................................................................................. 433 Wielowątkowość w aplikacji konsolowej.................................................................................. 433 Debugowanie aplikacji konsolowych........................................................................................ 436 Ustalanie argumentów wiersza poleceń za pomocą IDE ....................................................... 436 Przyłączanie debugera do uruchomionej aplikacji ................................................................ 436 Monitorowanie systemu plików ............................................................................................... 439 Podsumowanie....................................................................................................................... 440 4QFKC  #RNKMCELG YKGNQYæVMQYG  Przetwarzanie asynchroniczne bez udziału wątków.................................................................... 442 Stosowanie timera............................................................................................................. 442 Zdarzenie Application.Idle................................................................................................. 442 Lekkie wątki — pule wątków .................................................................................................. 444 Czym jest pula wątków?.................................................................................................... 444 Jak działa pula wątków? .................................................................................................... 445 Stosowanie puli wątków .................................................................................................... 445 Synchronizacja — WaitHandle .......................................................................................... 449 Synchronizacja z wykorzystaniem klasy Monitor................................................................. 455 Wielowątkowość — waga cię ka ............................................................................................. 457 Tworzenie i korzystanie z wątków...................................................................................... 457 Przykład wątku................................................................................................................. 457
    • Spis treści 13 Dołączanie atrybutu ThreadStatic ............................................................................................ 459 Wielowątkowość a formularze Windows .................................................................................. 461 Strategie wielowątkowości dla formularzy Windows............................................................ 462 Invoke i wywołania synchroniczne ..................................................................................... 462 Wywołania asynchroniczne — BeginInvoke i EndInvoke..................................................... 463 Podsumowanie....................................................................................................................... 466 4QFKC  5VQUQYCPKG HQTOWNCT[ 9KPFQYU Przegląd przestrzeni nazw Forms ............................................................................................. 467 Klasy przestrzeni nazw Forms............................................................................................ 468 Interfejsy przestrzeni nazw Forms ...................................................................................... 478 Struktury przestrzeni nazw Forms ...................................................................................... 479 Delegacje przestrzeni nazw Forms...................................................................................... 480 Wyliczenia przestrzeni nazw Forms.................................................................................... 481 Przegląd przestrzeni nazw System.Drawing .............................................................................. 482 Klasy przestrzeni nazw System.Drawing............................................................................. 482 Struktury przestrzeni nazw System.Drawing........................................................................ 489 Klasa Form ............................................................................................................................ 489 Powoływanie obiektu formularza ....................................................................................... 490 Projektowanie interfejsu u ytkownika................................................................................. 491 Dynamiczne tworzenie kontrolek ....................................................................................... 493 Procedury obsługi zdarzeń dynamicznie tworzonych kontrolek ............................................. 494 Wyszukiwanie aktywnego formularza................................................................................. 494 Dołączanie kodu do formularzy.......................................................................................... 494 Tworzenie formularzy u ytkownika za pomocą GDI+ ............................................................... 495 Podsumowanie....................................................................................................................... 495 4QFKC  2TQLGMVQYCPKG KPVGTHGLUW W [VMQYPKMC Rozmieszczanie kontrolek ....................................................................................................... 497 Kotwiczenie kontrolek....................................................................................................... 498 Dokowanie kontrolek ........................................................................................................ 499 Zachowanie marginesu kontrolek ....................................................................................... 499 Ustalanie poło enia i rozmiaru ........................................................................................... 499 Praca z Menu......................................................................................................................... 500 Definiowanie MainMenu i ContextMenu ............................................................................ 500 Dołączanie kodu menu ...................................................................................................... 501 Ró nice pomiędzy MainMenu i ContextMenu ..................................................................... 503 Dynamiczne dodawanie pozycji menu ................................................................................ 504 Zaawansowane techniki projektowania formularzy .................................................................... 507 Własność Form.AutoScale................................................................................................. 507 Automatyczne przewijanie................................................................................................. 507 Rozmiar AutoScrollMargin................................................................................................ 508 Stosowanie obiektu CreateParams ...................................................................................... 508 Czym zajmują się klasy Component i Control ........................................................................... 510 Klasa Component ............................................................................................................. 510 Klasa Control ................................................................................................................... 511 Dynamiczne dodawanie kontrolek............................................................................................ 512 Kontrolki u ytkownika — UserControls ................................................................................... 513 Wprowadzanie kontrolek do kontrolki u ytkownika............................................................. 513 Zdarzenia w kontrolkach u ytkownika ................................................................................ 514
    • 14 Visual Basic .NET. Księga eksperta Kod w kontrolkach u ytkownika ........................................................................................ 516 Umieszczanie kontrolki u ytkownika w Visual Studio .NET ................................................ 516 Przypisywanie kontrolce bitmapy pojawiającej się oknie narzędziowym ................................ 517 Tworzenie własnych kontrolek ................................................................................................ 517 Tworzenie niewidocznych komponentów............................................................................ 518 Określanie domyślnego zdarzenia....................................................................................... 519 Podsumowanie....................................................................................................................... 520 4QFKC  2TQITCOQYCPKG )&+  Podstawy GDI+ ..................................................................................................................... 521 Stosowanie obiektów Graphics........................................................................................... 522 Podstawowe klasy związane z rysowaniem ......................................................................... 524 Proste operacje z wykorzystaniem GDI+............................................................................. 525 Kreślenie figur płaskich i tekstu ......................................................................................... 526 Zaawansowane metody graficzne............................................................................................. 530 Kreślenie krzywych .......................................................................................................... 530 Kreślenie skomplikowanych krzywych — krzywe Bézier..................................................... 531 Ście ka graficzna — klasa GraphicsPath............................................................................. 532 Klasa Region .................................................................................................................... 537 Formularze o niestandardowych kształtach.......................................................................... 537 Klasa Icon........................................................................................................................ 540 Przestrzeń nazw Imaging ................................................................................................... 540 Grafika u ytkownika w formularzach Windows ........................................................................ 541 Drukowanie grafiki................................................................................................................. 542 Podsumowanie....................................................................................................................... 543 %ú è +8 $WFQYCPKG WU WI 999 9GD 5GTXKEGU  4QFKC  5VQUQYCPKG K KORNGOGPVCELC WU WI 999 9GD 5GTXKEGU  Przegląd usług Web Services ................................................................................................... 547 Wyszukiwanie usług Web Services za pomocą UDDI................................................................ 549 uddi.microsoft.com ........................................................................................................... 550 Lokalne usługi Web Services ............................................................................................. 550 Cztery aspekty pracy z Web Services.................................................................................. 551 Wywoływanie usług WWW .................................................................................................... 552 Odwołania do WebServices ............................................................................................... 552 Aplikacje formularzy Windows.......................................................................................... 554 Aplikacje formularzy WWW ............................................................................................. 555 Implementowanie usług WWW ............................................................................................... 556 Plik global.asax ................................................................................................................ 556 Plik web.config................................................................................................................. 557 Plik disco ......................................................................................................................... 559 Plik .asmx ........................................................................................................................ 560 Kiedy usługi Web Servcies mogą okazać się przydatne ........................................................ 561 Tworzenie usługi Web Service ........................................................................................... 562 Wybór metody dostępu sieciowego .......................................................................................... 566 Zarządzanie informacjami stanu............................................................................................... 567 Obsługa i generowanie wyjątków w usługach Web Services....................................................... 569
    • Spis treści 15 Debugowanie usług Web Services............................................................................................ 570 Zintegrowane debugowanie ............................................................................................... 571 Uruchamianie bez debugowania ......................................................................................... 571 Uruchamianie w przeglądarce ............................................................................................ 571 Kompilowanie i rozpowszechnianie projektów sieciowych......................................................... 572 Podsumowanie....................................................................................................................... 573 4QFKC  2TQITCOQYCPKG UKGEKQYG #520'6 Formularze WWW ................................................................................................................. 576 Okno projektowania formularzy WWW.............................................................................. 576 Kod formularzy WWW ..................................................................................................... 578 Kompilowanie i uruchamianie aplikacji ASP.NET............................................................... 580 Request i Response................................................................................................................. 580 ASP.NET i ADO.NET............................................................................................................ 581 Baza danych przykładowych programów ............................................................................ 582 Sortowanie danych w formularzu WWW ............................................................................ 584 Stronicowanie danych przy u yciu DataGrid ....................................................................... 586 Buforowanie danych wyjściowych ........................................................................................... 587 Dodawanie i usuwanie elementów bufora............................................................................ 590 Deklarowanie terminu wa ności elementów pamięci podręcznej ........................................... 591 Względy wydajnościowe......................................................................................................... 591 Przygotowywanie kontrolek do wyświetlenia ............................................................................ 592 Dynamiczne dodawanie kontrolek do strony ............................................................................. 594 Programowe dodawanie tekstu statycznego ......................................................................... 594 Modyfikowanie własności kontrolek przy u yciu kolekcji Attributes ..................................... 595 Programowe dodawanie kontrolek LiteralControl ................................................................ 595 Dodawanie kontrolek przy u yciu kontrolki PlaceHolder...................................................... 596 Programowe dodawanie kontrolek prezentacji danych.......................................................... 597 Wyposa anie kontrolek dynamicznych w procedury obsługi zdarzeń..................................... 598 Tworzenie własnych kontrolek WWW ..................................................................................... 599 Zapisywanie strony WWW jako kontrolki serwerowej ......................................................... 600 Tworzenie własnej kontrolki u ytkownika........................................................................... 606 Tworzenie biblioteki kontrolek WWW ............................................................................... 607 Podsumowanie....................................................................................................................... 609 4QFKC  &KGPPKM FCTG  Źródło zdarzeń ....................................................................................................................... 612 Tworzenia źródła zdarzeń.................................................................................................. 612 Usuwanie źródła zdarzeń ................................................................................................... 614 Pozyskiwanie tablicy dzienników zdarzeń........................................................................... 614 Wyszukiwanie nazwy logu na podstawie nazwy źródła ........................................................ 615 Usuwanie dziennika .......................................................................................................... 615 Dokonywanie wpisów do istniejącego dziennika ....................................................................... 615 Własny dziennik zdarzeń......................................................................................................... 617 Pobieranie zawartości dziennika zdarzeń .................................................................................. 618 Czyszczenie dziennika zdarzeń ................................................................................................ 620 Powiadamianie o zdarzeniu ..................................................................................................... 620 Zdalny dziennik zdarzeń ......................................................................................................... 621 EventLogTraceListener........................................................................................................... 621 Podsumowanie....................................................................................................................... 622
    • 16 Visual Basic .NET. Księga eksperta &QFCVMK   &QFCVGM # 'NGOGPV[ RTQITCOQYCPKC 8$ OKGPKQPG Y 8$0'6  Elementy usunięte z VB. NET................................................................................................. 625 Zmiany w deklaracji i składni .................................................................................................. 627 As Any ............................................................................................................................ 627 Deklarowanie zmiennych................................................................................................... 627 Numerowanie wierszy ....................................................................................................... 628 Zmiany zakresu widoczności zmiennych .................................................................................. 629 Zmiany w deklaracji procedur ................................................................................................. 629 Brak IsMissing ................................................................................................................. 630 Wywoływanie procedur..................................................................................................... 630 Przekazywanie własności przez referencję .......................................................................... 631 ByVal — domyślny modyfikator argumentu ....................................................................... 632 Argumenty ParamArray .................................................................................................... 632 Modyfikator Static ............................................................................................................ 633 Zmiany we własnościach......................................................................................................... 633 Ujednolicona deklaracja własności w Visual Basic .NET ..................................................... 634 Let nie jest ju obsługiwane ............................................................................................... 634 Własności domyślne nie mogą być współdzielone lub prywatne............................................ 634 Własności domyślne muszą pobierać argumenty.................................................................. 634 Argumenty własności nie mogą być przekazywane przez referencję...................................... 635 Zmiany zakresu tablic ............................................................................................................. 636 Rozmiar tablicy mo e się zmienić, ale liczba wymiarów jest stała ......................................... 636 Zmiany w typach danych ........................................................................................................ 637 Typ Currency ................................................................................................................... 637 Brak DefTyp .................................................................................................................... 637 Konstrukcja Type zastąpiona przez Structure ...................................................................... 637 Visual Basic .NET nie obsługuje ciągów tekstowych o ustalonej długości.............................. 638 Zmiany w wartościach całkowitoliczbowych ....................................................................... 638 Zmiany operatorów ................................................................................................................ 639 Operatory równowa ności i implikacji ................................................................................ 639 And, Or, Xor i Not............................................................................................................ 639 Szybkie oszacowanie......................................................................................................... 640 Zmiany w sterowaniu przebiegiem programu ............................................................................ 640 Wywołanie funkcji zamiast GoSub..................................................................................... 640 Brak On ... GoSub i On ... Goto ......................................................................................... 642 Zmiany w klasach i interfejsach ............................................................................................... 643 Parametryzowane konstruktory .......................................................................................... 643 Brak Option Private Module .............................................................................................. 643 Zmiany w interfejsach ....................................................................................................... 643 Zastąpione elementy programowania........................................................................................ 644 Arcustangens (Atn) ........................................................................................................... 644 Circle............................................................................................................................... 645 Debug.Print i Debug.Assert ............................................................................................... 645 DoEvents ......................................................................................................................... 645 IsNull .............................................................................................................................. 645 IsObject ........................................................................................................................... 645 Line................................................................................................................................. 646
    • Spis treści 17 LSet i RSet....................................................................................................................... 646 MsgBox ........................................................................................................................... 646 Wend............................................................................................................................... 646 Elementy programowania obsługiwane w inny sposób............................................................... 647 Calendar .......................................................................................................................... 647 Date ................................................................................................................................ 647 Empty zastąpiono przez Nothing ........................................................................................ 648 Now ................................................................................................................................ 648 Rnd i Round..................................................................................................................... 648 PSet i Scale nie są obsługiwane w Visual Basic .NET .......................................................... 649 Sgn i Sqr.......................................................................................................................... 649 String............................................................................................................................... 649 Time................................................................................................................................ 650 VarType .......................................................................................................................... 650 Typ Variant zastąpiony przez Object........................................................................................ 650 5MQTQYKF 
    • 4QFKC  6YQTGPKG MNCU Mo liwość definiowania klas i tworzenia ich egzemplarzy (instancji) jest jedną z naj- wa niejszych cech ka dego języka zorientowanego obiektowo. A do chwili obecnej Visual Basic nie obsługiwał w pełni obiektowości. Mimo e moduły w VB6 nazywane były modułami klas, tak naprawdę były interfejsami w sensie technologii COM (ang. Component Object Model). Oznacza to, e VB6 nie obsługiwał idiomu klasy; nie umo - liwiał korzystania z innej bardzo po ytecznej cechy programowania obiektowego — dziedziczenia. Zasadniczą ró nicą pomiędzy interfejsami, a klasami jest dziedziczenie. Ka da imple- mentacja interfejsu VB6 (modułu klasy) wymagała wprowadzenia wszystkich publicz- nych metod dla tego interfejsu. Klasy, w przeciwieństwie do interfejsu, obsługują dziedzi- czenie. Dziedziczenie oznacza, e mogą istnieć podklasy zawierające pola, właściwości, metody i zdarzenia klasy nadrzędnej. Tworząc nowe klasy, mo esz je wykorzystywać do rozszerzania istniejących klas bazowych. Zarówno zorientowane obiektowo klasy, jak i interfejsy COM udostępniają twórcom oprogramowania potę ne marzędzia do tworzenia i zarządzania zaawansowanymi pro- jektami. Obie technologie są bardzo przydatne i obie zostały zaimplementowane w Vi- sual Basic .NET. Dodatkowo, Microsoft udoskonalił i poprawił interfejsy i opisy klas w celu zapobiegnięcia niejednoznaczności podczas ich stosowania. Obie technologie po- siadają odmienne zasady składni. W tym rozdziale zostanie przedstawiona zmieniona składnia interfejsów oraz właściwości nowej definicji klasy, włączając w to dziedziczenie, polimorfizm, przecią anie i prze- słanianie metod. Dodatkowo, rozdział ten zawiera kolejne przykłady wykorzystania ob- sługi wyjątków i wielowątkowości w Visual Basic .NET. &GHKPKQYCPKG MNCU Klasa w Visual Basic .NET nie jest klasą VB6. Klasy VB6 są w VB .NET deklarowane i definiowane przy u yciu słowa kluczowego KPVGTHCEG. Klasy VB .NET są definiowa- nymi przez u ytkownika typami agregacyjnymi, umo liwiającymi dziedziczenie. Ró nią się one od interfejsów COM, które są dokładnie tym, czym w VB6 były moduły klasy.
    • 236 Część II Zaawansowane programowanie zorientowane obiektowo Wszystkie klasy w Visual Basic .NET są definiowane w pliku .VB (w przeciwieństwie do pliku .CLS), a w pliku takim mo e być zawarta jedna lub kilka klas. (Klasy, struktury i moduły mogą być zgromadzone w jednym pliku). Podstawowa składnia klasy jest na- stępująca: %NCUU ENCUUPCOG 'PF %NCUU Jeśli przez przypadek popełnisz błąd podczas deklarowania klasy, Visual Studio.NET IDE podkreśli linią falistą miejsce, w którym ten błąd występuje (zobacz rysunek 7.1) 4[UWPGM  Visual Studio .NET IDE zaznacza linią falistą miejsca zawierające błąd Najczęściej klasy poprzedzone są specyfikatorem dostępu 2WDNKE, mo esz jednak wyko- rzystać inne specyfikatory. W podrozdziale „U ywanie specyfikatorów dostępu do klas” znajdziesz więcej informacji na ten temat. Instrukcje %NCUU i 'PF %NCUU tworzą jednostkę hermetyzacji dla klasy. Wszystkie skła- dowe klasy umieszczane są pomiędzy tymi instrukcjami. Mo esz dodawać dowolną liczbę pól, właściwości, metod i zdarzeń w celu zdefiniowania klasy, która ma spełniać określone wymagania w dziedzinie rozwiązania jakiegoś pro- blemu. Jakkolwiek liczba składowych w klasie mo e być dowolna, jednak przestrzeganie następujących zasad w większości przypadków pozwoli na zachowanie przejrzystości w kodzie i uproszczenie tworzonych konstrukcji. Klasy powinny składać się z maksymalnie sześciu składowych publicznych, włączając w to właściwości i metody. Liczba składowych niepublicznych mo e być większa, gdy nie wpływają one na prostotę korzystania z klasy przez u ytkownika. W ogólnym przypadku jakiekolwiek składowe niepubliczne powinny być chronione i wirtualne — posiadając modyfikator QXGTTKFCDNG.
    • Rozdział 7. Tworzenie klas 237 Pola, właściwości, zdarzenia wspólnie określane są mianem składowych. Termin skła- dowa odnosi się po prostu do czegoś, co zostało zdefiniowane jako część klasy. Jak we wszystkich regułach, tak e i tu są wyjątki. Istnieje zasada „wystarczająco dobry”, wprowadzona przez Grady Boocha, mówiąca, e jeśli ró norodność oraz liczba składo- wych jest rozsądna i wystarczająca, to liczba ta jest wystarczająco dobra. W ksią ce Ja- mesa Coplien „Zaawansowany C++” zostały przedstawione zaawansowane zagadnienia, które łamią ogólne zasady. Kolejnym przykładem wyjątku od opisanych powy ej reguł są klasy ze wszystkimi składowymi typu 5JCTGF, jak np. klasa /CVJ w CLR. Jak zostało wspomniane wcześniej, podstawowe wskazówki do definiowania klas są do- brym punktem startowym, istnieją jednak inne zasady i motywacje, którymi mo na się kierować podczas tworzenia klas. Na przykład technika refaktoringu „Zastosuj obiekt pa- rametryczny”, której zastosowanie ulepsza przekazywanie parametrów, wymaga utwo- rzenia dodatkowych klas. 7 [YCPKG URGE[HKMCVQTÎY FQUVúRW FQ MNCU W Visual Basic .NET występuje pięć specyfikatorów dostępu, opisanych w kolejnych podrozdziałach. 2WDNKE Specyfikator dostępu 2WDNKE, zastosowany na poziomie klasy, jest najczęściej u ywa- nym specyfikatorem. Klasy publiczne są to klasy, do których przewidziany jest dostęp przez ka dego u ytkownika. Specyfikator dostępu 2WDNKE występuje w kodzie po atry- butach i bezpośrednio przed słowem kluczowym %NCUU. (W rozdziale 12., „Definiowa- nie atrybutów”, znajdziesz więcej informacji o atrybutach). 2WDNKE %NCUU /[%NCUU 'PF %NCUU 2TQVGEVGF Specyfikator 2TQVGEVGF ma zastosowanie wyłącznie w klasach zagnie d onych. Klasy zagnie d one są są dostępne wyłącznie w danej klasie i w klasach potomnych. Nie mo- esz zdefiniować składników egzemplarza klasy zagnie d onej z widocznością większą ni definicja klasy. Definicja zagnie d onej klasy 2TQVGEVGF%NCUU przedstawia się następująco: 2WDNKE %NCUU *CU2TQVGEVGF 2TQVGEVGF %NCUU 2TQVGEVGF%NCUU 'PF %NCUU 'PF %NCUU Klasa *CU2TQVGEVGF zawiera zagnie d oną klasę 2TQVGEVGF%NCUU. *CU2TQVGEVGF mo e implementować egzemplarze 2TQVGEVGF%NCUU, a klasy dziedziczące z *CU2TQVGEVGF mo- gą deklarować i tworzyć egzemplarze zagnie d onej klasy 2TQVGEVGF%NCUU.
    • 238 Część II Zaawansowane programowanie zorientowane obiektowo (TKGPF Klasy zaprzyjaźnione są dostępne wyłącznie w programie, w którym zostały zdefinio- wane. Jeśli dodasz specyfikator dostępu (TKGPF do definicji klasy, egzemplarze tej klasy mogą być tworzone wyłącznie w tym samym programie. Załó my, e mamy bibliotekę klas z klasą o trybie dostępu (TKGPF o nazwie (TKGPF%NCUU. Moglibyśmy utworzyć egzemplarze tej klasy w bibliotece klas, lecz nie mo emy uczynić tego z poziomu u ytkownika tej biblioteki. Mo na zatem powiedzieć, e (TKGPF%NCUU jest wyłącznie do u ytku wewnętrznego. Oto przykład: (TKGPF %NCUU (TKGPF%NCUU 2WDNKE 5JCTGF 5WD 2WDNKE/GVJQF /UI$QZ (TKGPF%NCUU2WDNKE/GVJQF 'PF 5WD 'PF %NCUU Korzystaj ze specyfikatora dostępu (TKGPF, gdy chcesz utworzyć klasę zawierającą detale implementacyjne biblioteki klas lub jakiejś innej aplikacji, uniemo liwiając tym samym dostęp do takiej klasy u ytkownikom danej aplikacji. 2TQVGEVGF (TKGPF Klasy 2TQVGEVGF (TKGPF reprezentują połączenie specyfikatorów 2TQVGEVGF i (TKGPF. Klasy chronione muszą być zagnie d one; z tego względu klasy 2TQVGEVGF (TKGPF rów- nie muszą być zagnie d one. Przykład pokazuje zagnie d oną klasę 2TQVGEVGF (TKGPF: 2WDNKE %NCUU *CU2TQVGEVGF(TKGPF 2TQVGEVGF (TKGPF %NCUU 2TQVGEVGF(TKGPF 2WDNKE 5JCTGF 5WD 6GUV /UI$QZ 6GZV 'PF 5WD 'PF %NCUU 'PF %NCUU Klasy 2TQVGEVGF (TKGPF są najczęściej wykorzystywane jako klasy realizacyjne dla klasy, która je zawiera. Metody definiowane w klasach zagnie d onych mogą być wywoływane pośrednio przez metody proxy zawierającej je klasy. Nie mo esz zwrócić egzemplarza klasy 2TQVGEVGF (TKGPF. Poni szy przykład, bazując na kodzie powy ej, jest więc niepoprawny: 2WDNKE %NCUU *CU2TQVGEVGF(TKGPF 2TQVGEVGF (TKGPF %NCUU 2TQVGEVGF(TKGPF 2WDNKE 5JCTGF 5WD 6GUV /UI$QZ 6GZV 'PF 5WD 'PF %NCUU 2WDNKE 5JCTGF (WPEVKQP (CEVQT[ #U 2TQVGEVGF(TKGPF 'PF (WPEVKQP 'PF %NCUU
    • Rozdział 7. Tworzenie klas 239 Taka definicja funkcji spowoduje wystąpienie błędu, wyraz 2TQVGEVGF(TKGPF zostanie podkreślony linią falistą, a w liście zadań pojawi się uwaga, e (CEVQT[ niewłaściwie udostępnia typ 2TQVGEVGF(TKGPF poza klasą RWDNKEPæ *CU2TQVGEVGF(TKGPF . 2TKXCVG Specyfikator dostępu 2TKXCVG ma zastosowanie wyłącznie w klasach zagnie d onych. Klasy zagnie d one 2TKXCVG reprezentują szczegóły implementacyjne danej klasy. Gdy pojawi się wewnętrzny problem, którego rozwiązanie jest bardziej zło one i wymaga mocy, jakiej nie są w stanie zapewnić proste metody, definiuje się wówczas zagnie - d oną klasę prywatną, która rozwiązuje ten problem. Przykład składni takiej klasy wy- gląda następująco: 2WDNKE %NCUU *CU2TKXCVG 2TKXCVG %NCUU 2TKXCVG%NCUU 'PF %NCUU 'PF %NCUU Egzemplarze 2TKXCVG%NCUU mogą być tworzone wyłącznie w egzemplarzach *CU2TKXCVG. Cel korzystania z klasy prywatnej pojawia się wówczas, gdy mamy grupę metod i wła- ściwości i musimy przechować wiele egzemplarzy stanu ka dego z tych obiektów. Ró - nica polega na tym, e nie chcemy, aby prywatne klasy zagnie d one były widoczne dla u ytkownika z zewnątrz. Stosunkowo rzadko w swych aplikacjach będziesz wykorzystywał klasy chronione i pry- watne. Miej jednak na uwadze, e takie konstrukcje istnieją i w razie potrzeby nie bój się ich u yć *GTOGV[CELC K WMT[YCPKG KPHQTOCELK Hermetyzacja i ukrywanie informacji to zagadnienia bezpośrednio związane z progra- mowaniem zorientowanym obiektowo; mogłeś się z nimi spotkać ju wcześniej. Termi- ny te dotyczą strategii programowania. Hermetyzacja literalnie oznacza dodawanie składowych — pól, właściwości, metod i zdarzeń — do klas lub struktur. Ogólną zasa- dą jest to, e składowe dodaje się w tych miejscach, w których ich pojawienie się będzie najbardziej korzystne; to znaczy, gdzie będą mogły być najczęściej wykorzystywane lub zapewnią najlepsze udoskonalenie Twojej implementacji. Konsument klasy jest to programista, który tworzy egzemplarze klasy. Twórca klasy (producent) mo e być równie jednocześnie konsumentem. Generalizer jest konsumentem, który będzie dziedziczył Twoje klasy. Ukrywanie informacji jest to przypisywanie egzemplarzom określonych mo liwości dostępu — mogą one być prywatne, chronione, publiczne i zaprzyjaźnione — w celu uwolnienia konsumentów lub generalizatorów od konieczności poznawania wszystkich składowych danej klasy lub struktury. Ograniczając liczbę składowych klasy, których muszą się oni nauczyć — poprzez właśnie ukrycie informacji — tworzone klasy są ła- twiejsze do wykorzystania.
    • 240 Część II Zaawansowane programowanie zorientowane obiektowo 5RGE[HKMCVQT[ FQUVúRW Do ukrywania informacji wykorzystuje się następujące specyfikatory dostępu: 2TKXCVG, 2TQVGEVGF, 2WDNKE, (TKGPF oraz 5JCFQYU (tymi ostatnimi zajmiemy się w dalszej części rozdziału). Kod klasy, który chcesz, aby był dostępny dla wszystkich, jest określany jako 2WDNKE. Mówimy, e interfejs publiczny jest utworzony ze składowych publicznych. Składowe 2WDNKE są implementowane dla potrzeb konsumentów klas. Gdy chcesz natomiast ukryć część informacji przed konsumentami publicznymi, jednak generalizatorzy mają mieć mo liwość dostępu do tej informacji, zastosuj specyfikator dostępu 2TQVGEVGF. Składowe 2TKXCVG słu ą wyłącznie do u ytku wewnętrznego i mówimy, e zawierają szczegóły implementacyjne klasy. Ze szczegółami tymi jedynie producent klasy musi być zaznajomiony. Ostatnie ze specyfikatorów — (TKGPF oraz 2TQVGEVGF (TKGPF — u ywane są w tych przypadkach, w których klasy wykorzystywane są przez jednostki w tej samej aplikacji. Dostęp zaprzyjaźniony oznacza dostęp wyłącznie wewnątrzaplikacyjny. Na przykład, jeśli definiujesz bibliotekę klas, a u ytkownicy z zewnątrz nie muszą lub nie powinni mieć dostępu do niektórych klas z tej biblioteki, oznaczasz je jako klasy (TKGPF. Ogólna zasada jest taka, e nale y wszystkie metody definiować jako 2TQVGEVGF, chyba e muszą być publiczne. Jeśli musisz ujawniać składowe, rób to bardzo rozsądnie i rozmyślnie. 2TCEC CUKúIKGO Zagadnienie zasięgu zostało rozszerzone w Visual Basic .NET o zasięg blokowy. Nowe reguły rządzące zasięgami zostały przedstawione w rozdziale 3., „Podstawy programo- wania w Visual Basic .NET”. Oprócz istniejących zasad i tych związanych z nowym zasięgiem blokowym, pojawił się nowy aspekt pracy — wsparcie dla dziedziczenia, wprowadzające dodatkowe względy, na które nale y zwracać uwagę. Gdy dziedziczysz z istniejącej klasy, Twoja nowa klasa posiada w swoim zasięgu wszystkie z odziedziczonych składników — 2TQVGEVGF, (TKGPF i 2WDNKE. Na szczęście, Visual Basic .NET nie pozwala na pojawienie się problemów z nazwami tych składni- ków; gdy wystąpi konflikt nazw, kompilator od razu o tym ostrze e. Będziesz mógł wówczas zmienić nazwy konfliktowych składników, tworząc dwie oddzielne jednostki, lub wykorzystać słowo 5JCFQYU do rozwiązania problemu. (Więcej informacji znaj- dziesz w podrozdziale „Korzystanie z modyfikatora Shadows”). &QFCYCPKG RÎN K Y C EKYQ EK Pole jest daną składową klasy. Pola mogą być składowymi typu 8CNWG6[RG, jak np. +P VGIGT lub &CVG, lub te typu zło onego, czyli strukturą, wyliczeniem lub klasą. Właści- wości są specjalnymi metodami, które ogólnie u ywane są do zapewnienia określonego dostępu do pól.
    • Rozdział 7. Tworzenie klas 241 Generalnie, pola są prywatnymi elementami klasy. Jeśli zapewniony jest dostęp do pola, jest to zrealizowane za pomocą właściwości. Z tego powodu pola są zazwyczaj prywat- ne, a właściwości — publiczne. Jednak e czasami pola nie są w ogóle udostępnione po- przez właściwości. Właściwości równie nie zawsze reprezentują pole. Czasami repre- zentują one dane istniejące w bazie danych, rejestrze systemowym, pliku INI lub inną wartość, nie będącą bezpośrednio polem. Motywacją tworzenia pól w postaci elementów prywatnych jest to, e nieograniczony dostęp do danych jest z natury ryzykowny. Rozwa my sposób przyrządzania sosu ho- lenderskiego. Jeśli ugotujesz ółtka zbyt szybko, dostaniesz jajecznicę. Jednak jeśli bę- dziesz powoli je gotował — kurek gazu w kuchence jest tu analogią do właściwości zmniejszającej lub zwiększającej ogień — otrzymasz prawidłową konsystencję sosu. Kurek gazu jest metaforą na określenie metody właściwości. Pole reprezentuje ilość ciepła, a kurek — właściwość umo liwiającą jej zmianę. Osoba obsługująca kuchenkę nie jest uprawniona do zwiększenia ilości gazu poza określoną wartość. Wydruki 7.1 oraz 7.2 przedstawiają dwie częściowe klasy reprezentujące kuchenkę oraz ustawianie ilości wy- pływającego gazu. 9[FTWM  Klasa reprezentująca pole i właściwość dla ustawień temperatury kuchenki gazowej  2WDNKE %NCUU 5VQXG   2TKXCVG (6GORGTCVWTG #U &QWDNG   2WDNKE 2TQRGTV[ 6GORGTCVWTG #U &QWDNG   )GV  4GVWTP (6GORGTCVWTG  'PF )GV   5GV $[8CN 8CNWG #U &QWDNG  &GDWI#UUGTV 8CNWG   #PF 8CNWG    +H (6GORGTCVWTG   6JGP 'ZKV 2TQRGTV[  (6GORGTCVWTG  8CNWG  &GDWI9TKVG.KPG (6GORGTCVWTG  'PF 5GV   'PF 2TQRGTV[   'PF %NCUU Na wydruku 7.1 widzimy zdefiniowane pole (6GORGTCVWTG jako &QWDNG, dostępne poprzez właściwość 6GORGTCVWTG. Metoda właściwości )GV zwraca wartość pola, a 5GV przypisuje nową wartość do wartości pola. W wierszu 13. sprawdzany jest warunek, czy nie zostały ustawione niedopuszczalne wartości temperatury podczas tworzenia klasy. Przy jej wdra- aniu metoda &GDWI#UUGTV zostanie wyłączona przez kompilator. Jeśli 5VQXG byłaby u y- wana do kontroli rzeczywistej kuchenki, na pewno nie chciałbyś, aby temperatura mogła przekroczyć mo liwości fizyczne kuchenki. W celu upewnienia się, e ustawienia tempe- ratury są prawidłowe podczas normalnej pracy urządzenia, w wierszu 13. skorzystano z lustrzanego warunku +H w celu utrzymania temperatury w dopuszczalnych granicach.
    • 242 Część II Zaawansowane programowanie zorientowane obiektowo Powróćmy teraz do dyskusji poświęconej gramatyce języka. Zauwa yłeś pewnie, e ko- rzysta się z prefiksu ( przy nazwach pól, a opuszcza się je w nazwach właściwości. Zwróć uwagę równie na zmianę sposobu deklaracji właściwości. W Visual Basic .NET deklaracja właściwości jest pisana w pojedynczej strukturze bloku. Metody )GV oraz 5GV są blokami zagnie d onymi pomiędzy słowami 2TQRGTV[ i 'PF 2TQRGTV[, które definiują granice właściwości. (Przypomnij sobie, e w VB6 metody )GV i 5GV były definiowane jako dwa oddzielne i niezale ne bloki). Wydruk 7.2 definiuje nową klasę o nazwie (WGN5[UVGO, która wykorzystuje ró ne techniki do zapewnienia, e ustawienia przepustnicy mieszczą się w dopuszczalnych granicach. 9[FTWM  Wykorzystanie wyliczenia w połączeniu z metodami właściwości w celu ograniczenia wartości pola  2WDNKE %NCUU (WGN5[UVGO   2WDNKE 'PWO 6JTQVVNG5GVVKPI  +FNG  %TWKUG  #EEGNGTCVG  'PF 'PWO   2TKXCVG (6JTQVVNG #U 6JTQVVNG5GVVKPI   2WDNKE 2TQRGTV[ 6JTQVVG #U 6JTQVVNG5GVVKPI   )GV  4GVWTP (6JTQVVNG  'PF )GV   5GV $[8CN 8CNWG #U 6JTQVVNG5GVVKPI  (6JTQVVNG  8CNWG  &GDWI9TKVG.KPG 8CNWG  'PF 5GV   'PF 2TQRGTV[   'PF %NCUU Wyliczenie 6JTQVVNG5GVVKPI definiuje trzy dopuszczalne stany przepustnicy: +FNG (bieg jałowy), %TWKUG (prędkość podró na) i #EEGNGTCVG (przyspieszanie). Jeśli wykorzy- stasz dyrektywę 1RVKQP 5VTKEV z tym wyliczeniem, klienci nie będą mogli ustawić nie- właściwej wartości 6JTQVVNG. 1RVKQP 5VTKEV zapewni, e wszystkie wartości przekazy- wane do metody 5GV właściwości 2TQRGTV[ będą z zakresu 6JTQVVNG5GVVKPI, czyli +FNG, %TWKUG lub #EEGNGTCVG. *GTOGV[CELC K Y C EKYQ EK Specyfikatory dostępu mogą być dodawane do ka dego składnika w klasie. W największej liczbie przypadków, właściwości będą deklarowane jako składowe 2WDNKE klasy lub struk- tury. Oczywiście mo esz zdefiniować właściwość z dowolnym innym specyfikatorem.
    • Rozdział 7. Tworzenie klas 243 Jedną ze strategii, gdzie stosuje się właściwości 2TQVGEVGF, są klasy, które konsumenci mogą czynić bardziej ogólnymi. Przez zadeklarowanie klasy z właściwościami chronio- nymi umo liwiasz generalizatorom podjęcie decyzji, czy awansować te właściwości do dostępu publicznego. Specyfikator dostępu jest umieszczany przed słowem kluczowym 2TQRGTV[. Jeśli nie dołą- czysz adnego specyfikatora, składowe będą miały dostęp publiczny. Przykłady umiesz- czania specyfikatorów są zawarte w wydrukach 7.2 oraz 7.3. Podawaj specyfikatory dostępu za każdym razem, gdy definiujesz składową. W rezultacie otrzymasz kod czytelny i jasny. &GHKPKQYCPKG Y C EKYQ EK KPFGMUQYCP[EJ Właściwości indeksowane są po prostu metodami właściwości posiadającymi obowiąz- kowy parametr. Parametr ten jest semantycznie traktowany jak indeks, ale po umieszcze- niu kodu w metodzie właściwości mo esz robić z nim, co zechcesz. Poni ej zostaną omówione cechy właściwości i ró nice pomiędzy właściwościami a właściwościami in- deksowanymi. Podstawowa, zwykła właściwość posiada metody )GV oraz 5GV. Pierwsza z nich zacho- wuje się jak funkcja i jest niejawnie wywoływana, gdy właściwość zostaje u yta jako wartość prawostronna. Metoda 5GV działa jak dane wykorzystywane jako wartości lewo- stronne i ustawia wartość odpowiadającą tej właściwości. W najprostszym wydaniu war- tość właściwości jest przechowywana w odpowiadającym jej polu. Zarówno właściwość, jak i pole są tego samego typu. Wydruk 7.2 demonstruje wykorzystanie prostej właściwo- ści, posiadającej metody )GV, 5GV oraz korzystającej z wartości pola. Zauwa , e definicja właściwości w wierszu 11. określa zwracany typ, lecz nie pobiera adnych argumentów. W przeciwieństwie do zwykłej właściwości, właściwość indeksowana posiada zdefi- niowany w nawiasach argument. Nie reprezentuje on wartości pola; jest raczej indek- sem do tej wartości. Konsekwencją obecności indeksu jest to, e odpowiadające pole musi być tablicą albo kolekcją, co zazwyczaj ma miejsce. Jednak e indeks mo e być u ywany do czegokolwiek, a parametr indeksowy nie musi być wartością liczbową. Podstawową ideą stojącą za korzystaniem z właściwości indeksowanych jest to, e mo- esz bezpiecznie opakować tablice i inne rodzaje kolekcji danych w metody właściwości. Cel tego działania jest taki sam, jak w przypadku opakowania pojedynczej danej w meto- dę właściwości: chcesz ochronić dane przed nadu ywaniem. Na wydruku 7.3 zostały zaprezentowane dwie właściwości indeksowane. Obie w rzeczywistości odnoszą się do tej samej tablicy, jednak odwołują się do niej na dwa ró ne sposoby. 9[FTWM  Właściwości indeksowane  2WDNKE %NCUU +PFGZGF   2TKXCVG (5VTKPIU #U 5VTKPI  ] ,GFGP  &YC  6T[ _   &GHCWNV 2WDNKE 2TQRGTV[ 5VTKPIU $[8CN +PFGZ #U +PVGIGT #U 5VTKPI  )GV  4GVWTP (5VTKPIU +PFGZ
    • 244 Część II Zaawansowane programowanie zorientowane obiektowo  'PF )GV  5GV $[8CN 8CNWG #U 5VTKPI  (5VTKPIU +PFGZ  8CNWG  'PF 5GV  'PF 2TQRGTV[   2TKXCVG 5WD 5YCR $[8CN 1NF+PFGZ #U +PVGIGT A  $[8CN 0GY+PFGZ #U +PVGIGT   &KO 6GOR #U 5VTKPI  (5VTKPIU 0GY+PFGZ  (5VTKPIU 0GY+PFGZ  (5VTKPIU 1NF+PFGZ  (5VTKPIU 1NF+PFGZ  6GOR  'PF 5WD   2WDNKE 2TQRGTV[ 0COGU $[8CN 0COG #U 5VTKPI #U +PVGIGT  )GV  4GVWTP #TTC[+PFGZ1H (5VTKPIU 0COG  'PF )GV   5GV $[8CN 8CNWG #U +PVGIGT  5YCR 0COGU 0COG  8CNWG  'PF 5GV  'PF 2TQRGTV[   'PF %NCUU W klasie +PFGZGF są zdefiniowane dwie właściwości indeksowane. Pierwsza z nich, o nazwie 5VTKPIU, rozpoczyna się w wierszu 5. i pobiera argument typu +PVGIGT. Para- metr ten został nazwany +PFGZ i literalnie funkcjonuje jako indeks do pola będącego ta- blicą łańcuchów, (5VTKPIU. Zwróć uwagę, w jaki sposób indeks ten jest wykorzystywa- ny w metodzie )GV w wierszach 6. – 8. i 5GV w wierszach 9. – 11. Wiersze 7. i 11. demonstrują intuicyjne u ycie indeksu i tablicy. Gdy egzemplarze właściwości +PFGZGF oraz 5VTKPIU są u yte jako wartości prawostronne, wówczas wywoływana jest metoda )GV. (Przykładem wykorzystania wartości prawostronnej jest instrukcja /UI$QZ +PFGZGF 5VTKPIU  ). Metoda )GV ma zastosowanie, gdy +PFGZGF2TQRGTV[ jest u ywana jako wartość lewostronna, jak w instrukcji +PFGZGF5VTKPIU   ,GFGP . Porównaj właściwości 5VTKPIU i 0COGU. W obu z nich argument pełni rolę indeksu. Wła- ściwości te zwracają wartości o określonych typach — 5VTKPI w przypadku 5VTKPIU (wiersz 5.) i +PVGIGT w przypadku 0COGU (wiersz 22.). Z tego względu 5VTKPIU jest wła- ściwością indeksowaną typu 5VTKPI, a 0COGU — właściwością indeksowaną typu +PVG IGT. 0COGU pobiera jako argument łańcuch znaków, 0COG, i zwraca pozycję tego łańcucha w postaci indeksu odpowiadającej tablicy. W wierszu 24. u yta jest metoda 5JCTGF o nazwie 5[UVGO#TTC[+PFGZ1H, która pobiera tablicę i poszukiwany obiekt, a zwraca indeks tego obiektu w pobranej tablicy. W wier- szu 28. widzimy wywołanie 5YCR z wykorzystaniem bie ącego indeksu istniejącego elementu (znalezionego za pomocą metody )GV) oraz nowego indeksu reprezentowane- go przez 8CNWG. Element tablicy jest przenoszony ze starej pozycji do nowej. Poni szy fragment pokazuje, w jaki sposób mo esz znaleźć właściwość 0COGU u ytą w kodzie: &KO /[+PFGZGF #U 0GY +PFGZGF /[+PFGZGF0COGU ,GFGP  
    • Rozdział 7. Tworzenie klas 245 Gdy kod z wiersza 2. powy szego fragmentu zostanie wykonany, wartość pola — tabli- cy (5VTKPIU — jest równa ] &YC  ,GFGP  6T[ _. Wartość na pozycji odpowiada- jącej nazwie „Jeden” jest przenoszona do indeksu 1 poprzez zamianę miejscami z war- tością elementu o indeksie 1. -QT[ EK G UVQUQYCPKC Y C EKYQ EK KPFGMUQYCP[EJ Korzyści ze stosowania właściwości indeksowanych są wielorakie. Oczywistą korzyścią jest to, e dane powinny być chronione przez metody bez wpływu na łatwość korzystania z nich. To, e dane są tablicami czy kolekcją, nie oznacza, e nie powinny być chronione przed niewłaściwym u yciem. Być mo e nie tak oczywistą zaletą jest równie to, e bar- dziej zło one kolekcje danych mogą być łatwiejsze do u ycia poprzez wskazanie, e wła- ściwość indeksowana ma być właściwością domyślną. (Więcej na ten temat za chwilę). Wydruk 7.3 nie pokazuje ochrony danych przed nadu yciem. W naszej aplikacji musie- libyśmy zapewnić sprawdzanie, czy nie są u ywane niewłaściwe indeksy lub nazwy. Spójrzmy zatem, w których miejscach kodu mo emy wprowadzić usprawnienia. Za- cznijmy od metody +PFGZGF0COGU. Co stałoby się, gdybyśmy za ądali +PFGZGF0COGU %VGT[ ? Patrząc na istniejący kod — metoda #TTC[+PFGZ1H zwróciłaby wartość . Odpowiada nam takie rozwiązanie, po- zostawiamy więc 0COGU )GV bez zmian. Alternatywnie, moglibyśmy wygenerować wy- jątek, jeśli nazwa nie zostałaby znaleziona, jednak ju teraz przy podaniu niewłaściwego indeksu jest on podnoszony. W rezultacie ten fragment kodu jest w porządku. Przyjrzyjmy się teraz metodzie 5GV właściwości 0COGU. Nie ma w niej adnego sprawdza- nia poprawności danych. Mo emy sprawdzić, jak zachowuje się fragment kodu w przy- padku podania błędnych danych — jeśli u yty zostanie zły indeks, powinien wystąpić wyjątek. Faktycznie, +PFGZGF0COGU 5GUE   podnosi 5[UVGO+PFGZ1WV1H4CPIG 'ZEGRVKQP. Wywołujący musi prawdopodobnie wiedzieć, e popełnił błąd, więc wystą- pienie wyjątku jest rozsądne. Z drugiej strony, informacja pokazująca się w momencie wystąpienia wyjątku jest zbyt ogólna i mo emy uznać, e nas nie zadowala (zobacz ry- sunek 7.2). 4[UWPGM  Informacja pojawiająca się w chwili wystąpienia wyjątku przy niewłaściwym użyciu indeksu w obiekcie System.Array Dla celów praktycznych, jeśli domyślna informacja o wyjątku zapewnia wystarczającą informację, nie ma potrzeby pisania dodatkowego kodu do jego obsługi. Pamiętaj, że zawsze możesz obsłużyć wyjątek dodatkową procedurą. Dla celów demonstracyjnych załó my, e domyślne zachowanie się wyjątku nie jest wy- starczające. Zaimplementujemy rozszerzoną jego obsługę, aby zapewnić konsumentom klasy +PFGZGF dodatkowe informacje.
    • 246 Część II Zaawansowane programowanie zorientowane obiektowo /QF[HKMCELC OGVQF[ 5GV Y C EKYQ EK 0COGU Praktyczna modyfikacja tej metody ma na celu poinformowanie konsumenta, e u ył niewłaściwego indeksu. Będzie ona polegać na dodaniu we właściwości 0COGU nowych funkcji i modyfikacji metody 5GV. Na wydruku 7.4 przedstawiono zmiany dokonane w stosunku do kodu z wydruku 7.3. 9[FTWM  Dodanie kodu umożliwiającego obsługę błędu wynikającego z niewłaściwego użycia indeksu  2TKXCVG (WPEVKQP 8CNKF+PFGZ $[8CN +PFGZ #U +PVGIGT #U $QQNGCP  4GVWTP +PFGZ  (5VTKPIU)GV.QYGT$QWPF  #PF A  +PFGZ  (5VTKPIU)GV7RRGT$QWPF   'PF (WPEVKQP   2TKXCVG 1XGTNQCFU 5WD 8CNKFCVG $[8CN 0COG #U 5VTKPI  8CNKFCVG 0COGU 0COG  'PF 5WD   2TKXCVG 1XGTNQCFU 5WD 8CNKFCVG $[8CN +PFGZ #U +PVGIGT  +H 0QV 8CNKF+PFGZ +PFGZ 6JGP  6JTQY 0GY #RRNKECVKQP'ZEGRVKQP +PFGZ LGUV PKGRQRTCYP[O KPFGMUGO  'PF +H  'PF 5WD   2WDNKE 2TQRGTV[ 0COGU $[8CN 0COG #U 5VTKPI #U +PVGIGT  )GV  4GVWTP #TTC[+PFGZ1H (5VTKPIU 0COG  'PF )GV   5GV $[8CN 8CNWG #U +PVGIGT  8CNKFCVG 0COG  5YCR 0COGU 0COG  8CNWG  'PF 5GV  'PF 2TQRGTV[ Zmiana w metodzie 5GV właściwości 0COGU polega na dodaniu wywołania do funkcji 8C NKFCVG. Wiemy, e moglibyśmy sprawdzać poprawność indeksu bezpośrednio w meto- dzie 5GV, lecz we wcześniejszych rozdziałach omawialiśmy zalety i cel stosowania tech- niki refaktoringu „Wydzielanie metod”. W kodzie powy ej utworzyliśmy osobną funkcję 8CNKFCVG głównie po to, aby 5GV była jak najkrótsza i najprostsza oraz aby mieć mo li- wość wielokrotnego wykorzystania kodu 8CNKFCVG. Zastosowaliśmy przy tym dwie przecią one wersje 8CNKFCVG. Pierwsza z nich pobiera nazwę jako argument i wywołuje drugą wersję, pobierającą indeks. (Kolejną właściwością, gdzie moglibyśmy wprowa- dzić kod sprawdzający poprawność, jest 5VTKPIU, która wykorzystuje indeks całkowity) Aby uczynić kod bardziej czytelnym, zaimplementowaliśmy sprawdzanie wartości in- deksu w postaci metody 8CNKF+PFGZ (wiersze 1. – 4.). Jeśli indeks jest niepoprawny, ge- nerowany jest wyjątek w wierszu 12. Zauwa , e w kodzie nie ma komentarzy. Zastosowanie krótkich, zwięzłych i jasnych metod czyni komentarze zbędnymi.
    • Rozdział 7. Tworzenie klas 247 6YQTGPKG RQFMNCU[ MNCU[ Y[LæVMW Przypuśćmy, e chcemy wykorzystać kod wyrzucający wyjątek w wierszu 12. na wydru- ku 7.4 w kilku innych miejscach programu i być mo e nawet w innych klasach. Załó my równie , e klasa +PFGZGF reprezentuje bardzo istotną i wa ną część tworzonego systemu. Więcej informacji na temat obsługi wyjątków znajdziesz w rozdziale 5., „Procedury, funkcje i struktury”, a na temat dziedziczenia — w rozdziale 10., „Dziedziczenie i polimorfizm”. Moglibyśmy więc wprowadzić osobną klasę wyjątku, która hermetyzowałaby obsługę błędnych indeksów. Jest to mo liwe poprzez utworzenie podklasy z istniejącej klasy obsługi wyjątku i rozszerzenie jej działania. Podejście to jest jak najbardziej prawidło- we i wielu programistów innych języków od lat wykorzystuje rozszerzone klasy wyjąt- ków w swoich aplikacjach. Zało yliśmy, e nasza klasa +PFGZGF jest istotna oraz e kod obsługi wyjątku wyrzuca- nego ze względu na niepoprawny indeks będzie wykorzystywany wielokrotnie. W po- mocy Visual Studio .NET mo emy przeczytać, e jeśli chcemy utworzyć własną obsłu- gę wyjątków, powinniśmy skorzystać z klasy 5[UVGO#RRNKECVKQP'ZEGRVKQP. Warunkiem wystąpienia błędu w naszej aplikacji jest przekazanie nieprawidłowego in- deksu do metody 5GV właściwości 0COGU klasy +PFGZGF. Wyjątek jest generowany w wier- szu 12. wydruku 7.4, gdy sprawdzanie poprawności zakończy się niepowodzeniem. Takie zachowanie się kodu jest funkcjonalne, nie będziemy więc zmieniać organizacji w tym miejscu. Zmienimy jednak zaanga owane w to obiekty, co prezentuje wydruk 7.5. 9[FTWM  Kompletny wydruk klasy Indexed, zawierający nową klasę wyjątku  2WDNKE %NCUU +PFGZGF'ZEGRVKQP  +PJGTKVU #RRNKECVKQP'ZEGRVKQP   2WDNKE 5WD 0GY $[8CN 5VT #U 5VTKPI  /[$CUG0GY 5VT  'PF 5WD   2WDNKE 5JCTGF 5WD 6JTQY'ZEGRVKQP $[8CN +PFGZ #U +PVGIGT  6JTQY 0GY +PFGZGF'ZEGRVKQP +PFGZ LGUV PKGRQRTCYP[O KPFGMUGO  'PF 5WD   'PF %NCUU   2WDNKE %NCUU +PFGZGF   2TKXCVG (5VTKPIU #U 5VTKPI  ] ,GFGP  &YC  6T[ _   &GHCWNV 2WDNKE 2TQRGTV[ 5VTKPIU $[8CN +PFGZ #U +PVGIGT #U 5VTKPI  )GV  4GVWTP (5VTKPIU +PFGZ  'PF )GV   5GV $[8CN 8CNWG #U 5VTKPI  (5VTKPIU +PFGZ  8CNWG  'PF 5GV  'PF 2TQRGTV[
    • 248 Część II Zaawansowane programowanie zorientowane obiektowo   2TKXCVG 5WD 5YCR $[8CN 1NF+PFGZ #U +PVGIGT A  $[8CN 0GY+PFGZ #U +PVGIGT   &KO 6GOR #U 5VTKPI  (5VTKPIU 0GY+PFGZ  (5VTKPIU 0GY+PFGZ  (5VTKPIU 1NF+PFGZ  (5VTKPIU 1NF+PFGZ  6GOR  'PF 5WD   2TKXCVG (WPEVKQP 8CNKF+PFGZ $[8CN +PFGZ #U +PVGIGT #U $QQNGCP  4GVWTP +PFGZ  (5VTKPIU)GV.QYGT$QWPF  #PF A  +PFGZ  (5VTKPIU)GV7RRGT$QWPF   'PF (WPEVKQP   2TKXCVG 1XGTNQCFU 5WD 8CNKFCVG $[8CN 0COG #U 5VTKPI  8CNKFCVG 0COGU 0COG  'PF 5WD   2TKXCVG 1XGTNQCFU 5WD 8CNKFCVG $[8CN +PFGZ #U +PVGIGT  +H 0QV 8CNKF+PFGZ +PFGZ 6JGP  6JTQY 0GY #RRNKECVKQP'ZEGRVKQP +PFGZ LGUV PKGRQRTCYP[O KPFGMUGO  +PFGZGF'ZEGRVKQP6JTQY'ZEGRVKQP +PFGZ  'PF +H  'PF 5WD   2WDNKE 2TQRGTV[ 0COGU $[8CN 0COG #U 5VTKPI #U +PVGIGT  )GV  4GVWTP #TTC[+PFGZ1H (5VTKPIU 0COG  'PF )GV   5GV $[8CN 8CNWG #U +PVGIGT  8CNKFCVG 0COG  5YCR 0COGU 0COG  8CNWG  'PF 5GV  'PF 2TQRGTV[   'PF %NCUU Nowa klasa wyjątku jest zdefiniowana w pierwszych dwunastu wierszach. W wierszu 2. następuje wskazanie, e +PFGZGF'ZEGRVKQP dziedziczy z 5[UVGO#RRNKECVKQP'ZEGRVKQP. W argonie programowania obiektowego mówi się, e jest to relacja +U#. Zunifikowany język modelowania (ang. Unified Modeling Language — UML) określa dziedziczenie generalizacją. Mówimy, e +PFGZGF'ZEGRVKQP jest #RRNKECVKQP'ZEGRVKQP. +PFGZGF'ZEGRVKQP wprowadza przecią onego konstruktora, który pobiera argument w po- staci łańcucha. Argument ten — wiersz 4. — stanie się częścią komunikatu naszego wy- jątku. W wierszu 5. u ywana jest zmienna /[$CUG, która odnosi się do klasy bazowej. /[$CUG jest dostępna podobnie jak zmienna /G, która jest referencją do samej siebie. W wierszu 8. definiowana jest metoda 5JCTGF 6JTQY'ZEGRVKQP. Metoda 5JCTGF, która two- rzy egzemplarz obiektu, jest nazywana metodą fabryczną. Metoda taka umo liwia zlokali- zowanie konstrukcji i zainicjowanie obiektu, zmniejszając potrzebę duplikowania kodu tworzącego obiekt. I w końcu, procedura 8CNKFCVG zastępuje instrukcję z wiersza 12. wy- druku 7.4 na wywołanie do nowej metody fabrycznej, która tworzy i wyrzuca wyjątek. (Oryginalna instrukcja i jej zastąpienie są odpowiednio w wierszach 47. i 48. wydruku 7.3.).
    • Rozdział 7. Tworzenie klas 249 W chwili obecnej znasz ju sposoby definiowania właściwości indeksowanych, doda- wania kodu sprawdzającego do metod właściwości oraz wiesz, jak wprowadzać nowe klasy obsługi wyjątków. Jeśli dziedziczenie jest dla Ciebie pojęciem niejasnym, więcej informacji na jego temat znajdziesz w rozdziale 10., „Dziedziczenie i polimorfizm”. -QT[UVCPKG Y C EKYQ EK FQO[ NP[EJ Visual Basic .NET umo liwia korzystanie z właściwości domyślnych &GHCWNV, jednak w przeciwieństwie do VB6, w VB .NET jedynie właściwości indeksowane mogą być domyślne. Powód tego jest przedstawiony poni ej. W VB6 korzystaliśmy z metody 5GV podczas przypisywania referencji obiektu do zmien- nej obiektowej. Ponadto, jeśli element przypisywany był obiektem i nie było obecnej in- strukcji 5GV, VB6 wnioskował, e programista zamierza wykorzystać właściwość &G HCWNV. Z tego powodu właściwości domyślne w VB6 nie musiały być właściwościami indeksowanymi. Istnienie słowa kluczowego 5GV stanowiło wystarczającą wskazówkę dla kompilatora. Visual Basic .NET nie wykorzystuje 5GV do przypisywania obiektów. Z tego względu obecność obiektu, a nieobecność 5GV nie są wystarczające dla kompilatora do określenia Twoich zamiarów. W Visual Basic .NET podpowiedzią dla kompilatora, e chcemy sko- rzystać z właściwości &GHCWNV, jest obecność nawiasów przy nazwie obiektu. Wypływa stąd wniosek, e w VB .NET wszystkie właściwości &GHCWNV muszą być właściwościami indeksowanymi oraz mo liwe jest posiadanie tylko jednej właściwości domyślnej. Również w wersji obiektowej Pascala — Object Pascal — jedynie właściwości indeksowane mogą być domyślne. Obecność QDLGEV=? w tym języku jest wskazówką dla kompilatora, że programiście chodzi raczej o właściwość indeksowaną niż o przypisanie obiektu. Jest możliwe — i bardzo prawdopodobne — że zmiana wprowadzona we właściwościach domyślnych była dokonana częściowo pod wpływem Andersa Hejlsberga. Hejlsberg, w chwili obecnej Wyróżniony Inżynier (Distinguished Engineer) w Microsoft, był kierownikiem sekcji architektów w firmie Borland i odegrał zasadniczą rolę w procesie implementacji Delphi, stworzonego w Object Pascal. To nie jedyny wpływ Object Pascala na elementy Visual Basic .NET. Nie można jednak powiedzieć, że VB .NET jest podobny do Pascala; należałoby raczej stwierdzić, że Visual Basic .NET jest językiem rozwijającym się i Microsoft podjął bardzo mądrą decyzję, udoskonalając go z uwzględnieniem zalet innych języków. Trzeba się przyzwyczaić do tego, że Visual Basic .NET jest produktem silnie zmienionym i mocno udoskonalonym, jednak cały czas jest to Visual Basic. Aby wskazać, e właściwość ma być właściwością domyślną, umieść słowo kluczowe &GHCWNV w wierszu, w którym definiujesz właściwość, bezpośrednio przed specyfikato- rem dostępu. Fragment wydruku 7.5 pokazuje sposób umieszczania słowa &GHCWNV, czyniąc 5VTKPIU właściwością domyślną: &GHCWNV 2WDNKE 2TQRGTV[ 5VTKPIU $[8CN +PFGZ #U +PVGIGT #U 5VTKPI )GV 4GVWTP (5VTKPIU +PFGZ 'PF )GV
    • 250 Część II Zaawansowane programowanie zorientowane obiektowo 5GV $[8CN 8CNWG #U 5VTKPI (5VTKPIU +PFGZ  8CNWG 'PF 5GV 'PF 2TQRGTV[ Zakładając, e zadeklarowaliśmy egzemplarz +PFGZGF, u ywając instrukcji &KO +PFGZGF 1DLGEV #U 0GY +PFGZGF, dostęp do właściwości 5VTKPIU jest mo liwy poprzez wywołanie: /UI$QZ +PFGZGF1DLGEV5VTKPIU  lub, ze względu na to, e 5VTKPIU jest właściwością domyślną: /UI$QZ +PFGZGF1DLGEV  Podsumowując, właściwości domyślne muszą być indeksowane, mo esz mieć tylko jedną właściwość domyślną w klasie i mo esz wywoływać metody )GV i 5GV właściwości do- myślnej, korzystając z zapisu pełnego lub skróconego. -QT[UVCPKG OQF[HKMCVQTÎY Y C EKYQ EK Oprócz specyfikatorów dostępu, istnieją równie specjalne modyfikatory, które wystę- pują tylko przy właściwościach. Są to modyfikatory 4GCF1PN[ oraz 9TKVG1PN[. Właściwość tylko do odczytu (read-only) mo e być wykorzystywana wyłącznie jako argument prawostronny. To znaczy, u ytkownicy takiej metody mogą jedynie odczyty- wać właściwość, nie mogą jej modyfikować. Taka właściwość posiada więc jedynie metodę )GV. Konsumenci klasy mogą traktować właściwości 4GCF1PN[ jak stałe lub nie- zmienne dane, lecz nale y pamiętać, e mo e istnieć mechanizm wewnętrzny w stosun- ku do obiektu, który mo e zmienić odpowiadającą właściwości wartość, mimo e kon- sument nie ma takiej mo liwości. Właściwość tylko do zapisu (write-only) mo e być modyfikowana przez konsumenta, ale nie mo e zostać przez niego oglądana. W nich zaimplementowana jest wyłącznie metoda 5GV. Zewnętrzny blok właściwości jest w obu przypadkach identyczny, z wyjątkiem obecno- ści modyfikatora. Wewnętrznie właściwości 4GCF1PN[ posiadają jedynie metodę )GV, a 9TKVG1PN[ — metodę 5GV. +ORNGOGPVQYCPKG Y C EKYQ EK 4GCF1PN[ Przykładem właściwości tylko do odczytu mo e być zwracanie znacznika czasowego podczas tworzenia obiektu. Poniewa obiekt mo e być utworzony tylko raz — mimo e mo emy mieć wiele egzemplarzy klasy, to dany egzemplarz jest tworzony tylko jeden raz — nie ma sensu, aby umo liwiać konsumentom modyfikację daty utworzenia obiektu. Jeśli musisz śledzić, jak długo dany obiekt istnieje, i chcesz mieć pewność, e konsu- menci nie zmienią znacznika czasu tego obiektu, mo esz zdefiniować właściwość tylko do odczytu %TGCVG6KOG i zainicjować ją w konstruktorze:
    • Rozdział 7. Tworzenie klas 251 2WDNKE 5WD 0GY /[$CUG0GY (%TGCVG6KOG  0QY 'PF 5WD 2TKXCG (%TGCVG6KOG #U &CVG 2WDNKE 4GCF1PN[ 2TQRGTV[ %TGCVG6KOG #U &CVG )GV 4GVWTP (%TGCVG6KOG 'PF )GV 'PF 2TQRGTV[ Zwróć uwagę na poło enie modyfikatora 4GCF1PN[. Publiczna właściwość %TGCVG6KOG jest zdefiniowana jako tylko do odczytu i z tego powodu posiada wyłącznie blok )GV. Konstruktor — 5WD 0GY — inicjuje odpowiadające właściwości pole, (%TGCVG6KOG, w momencie wywołania konstruktora. Innym przykładem wykorzystania właściwości tylko do odczytu jest pole obliczone. Je- śli właściwość nie posiada odpowiadającej wartości, a jej wartość jest gdzieś obliczana, nie ma sensu implementacja metody 5GV. Weźmy pod uwagę symetryczną właściwość 'NCRUGF6KOG. Jeśli chcielibyśmy określić czas, jaki upłynął od uruchomienia aplikacji, moglibyśmy zwrócić ten czas jako wynik odjęcia od bie ącego czasu czas %TGCVG6KOG: 2WDNKE 4GCF1PN[ 2TQRGTV[ 'NCRUGF6KOG #U 6KOG5RCP )GV 4GVWTP &CVGQRA5WDVTCEVKQP 0QY (%TGCVG6KOG 'PF )GV 'PF 2TQRGTV[ Właściwość 'NCRUGF6KOG jest tylko do odczytu, gdy odpowiadająca jej wartość jest ob- liczana dynamicznie za ka dym razem, gdy właściwość jest wywoływana. Przy okazji widzimy wykorzystanie klasy 6KOG5RCP, której implementacja w powy szym kodzie umo liwia bardzo dokładny pomiar czasu. Inną cechą kodu jest wywołanie współdzie- lonej metody &CVGQRA5WDVTCEVKQP. Visual Basic .NET nie zezwala jeszcze na przecią- anie operatorów, więc zaimplementowane zostały specjalne metody z prefiksem QRA w miejscach, gdzie zachowanie się ich jest analogiczne do operatora przecią onego, który mógłby wystąpić np. w przypadku pisania kodu w C#. 'NCRUGF6KOG zwraca ró nicę pomiędzy 0QY i czasem utworzenia obiektu. Mo esz przete- stować obie właściwości za pomocą kilku wierszy kodu: &KO 1 #U 0GY 2TQRGTV[/QFKHKGTU 5[UVGO6JTGCFKPI6JTGCF5NGGR  /UI$QZ 1'NCRUGF6KOG6Q5VTKPI W wierszu 1. tworzony jest egzemplarz klasy 2TQRGTV[/QFKHKGTU, zawierający predefi- niowane właściwości, o których dyskutowaliśmy. Konstruktor inicjuje pole (%TGCVG6K OG. Druga instrukcja korzysta z metody 5NGGR, która usypia bie ący wątek. W naszym przypadku jest to 1000 milisekund, czyli 1 sekunda. W wierszu 3. wywoływana jest metoda właściwości 'NCRUGF6KOG, która zwraca obiekt 6KOG5RCP. Na końcu wywoływa- na jest metoda 6Q5VTKPI przy u yciu niejawnej referencji do obiektu 6KOG5RCP.
    • 252 Część II Zaawansowane programowanie zorientowane obiektowo Te trzy proste wiersze kodu powodują w rezultacie wyświetlenie okna komunikatu po- kazanego na rysunku 7.3. Zgodnie z jego zawartością wygląda na to, e Visual Basic .NET potrzebował około 1,4 milisekundy na wywołanie funkcji 0QY od momentu obu- dzenia wątku. 4[UWPGM  Okno dialogowe prezentujące rozdzielczość klasy TimeSpan w Visual Basic .NET +ORNGOGPVQYCPKG Y C EKYQ EK 9TKVG1PN[ Właściwości tylko do zapisu są wykorzystywane rzadziej ni wcześniej omawiane 4G CF1PN[, jednak istnieje kilka dobrych powodów, dla których ich sporadyczne wykorzy- stanie jest pomocne. Jedną z takich okazji jest właściwość związana z ustalaniem hasła. Przypuśćmy, e mamy klasę sprawdzania to samości u ytkownika, która akceptuje na- zwę u ytkownika i zamaskowane hasło. O ile odpowiedź na zapytanie obiektu klienta „Kto jest u ytkownikiem” byłaby wskazana, o tyle podobna odpowiedź na pytanie „Jakie jest jego hasło” byłaby ju bardziej ryzykowna. W takim przypadku chcesz zapewne, aby u ytkownik mógł wpisać hasło, ale jednocześnie eby aden z obiektów klienta nie mógł tej informacji uzyskać. Właściwość ta mogłaby więc być zaimplementowana w spo- sób następujący: 2TKXCVG (2CUUYQTF #U 5VTKPI 2WDNKE 9TKVG1PN[ 2TQRGTV[ 2CUUYQTF #U 5VTKPI 5GV $[8CN 8CNWG #U 5VTKPI (2CUUYQTF  8CNWG 'PF 5GV 'PF 2TQRGTV[ Zauwa , e edytor kodu utworzył tylko blok 5GV, a wartość przypisywana do właściwo- ści jest przechowywana w odpowiadającym polu. Z przyczyn praktycznych mo esz zmodyfikować ten kod, aby był jeszcze bardziej bez- pieczny. Na przykład mo esz zaimplementować właściwość 9TKVG1PN[, która będzie od razu sprawdzać hasło w metodzie 5GV tej właściwości, a potem wyczyści zmienną za- wierającą hasło. A informacją przechowywaną będzie jedynie to, czy podane hasło było poprawne. Taka zmiana zapobiegnie mo liwości podglądnięcia obszaru pamięci odpo- wiadającej zawartości klasy przez programu szpiegujące. Inne modyfikatory właściwości, jak 5JCFQYU, mogą być u ywane zarówno z właściwo- ściami, jak i z metodami. Aby uniknąć nadmiarowości informacji w Twoim kodzie, przyjmij, e modyfikatory mogą być stosowane w dowolnych składnikach klas, chyba e tekst wskazuje na coś innego. 9TKVG1PN[ i 4GCF1PN[ mo na stosować wyłącznie we właściwościach.
    • Rozdział 7. Tworzenie klas 253 &GHKPKQYCPKG Y C EKYQ EK YURÎ FKGNQP[EJ Obszerna i wyczerpująca dyskusja na temat składowych 5JCTGF została zawarta w roz- dziale 11., „Składowe współdzielone”. Tam równie znajdziesz przykłady ich stosowa- nia W tej chwili wystarczy powiedzieć, e właściwości mogą być współdzielone (5JCTGF) lub występować jako składowe egzemplarzy. Właściwości 5JCTGF oznaczają, e mo esz je wywołać w klasie — właściwość taka jest definiowana z u yciem słowa 5JCTGF. Skła- dowe 5JCTGF mogą być tak e wywołane przez egzemplarze, za to składowe egzemplarzy mogą być wywołane jedynie za pomocą egzemplarza klasy. Oto przykład: 2WDNKE 5JCTGF 4GCF1PN[ 2TQRGTV[ 0COG #U 5VTKPI )GV 4GVWTP 2TQRGTV[/QFKHKGTU 'PF )GV 'PF 2TQRGTV[ W przykładzie zdefiniowana jest właściwość 2WDNKE, 5JCTGF i 4GCF1PN[ o nazwie 0COG. Poniewa nazwa klasy nigdy się nie zmienia, chyba e zmiany dokona programista w kodzie programu, powy sza metoda mo e mieć charakter tylko do odczytu. Zrobienie metody publiczną oznacza, e konsumenci mogą z tej metody korzystać, a u ycie mo- dyfikatora 5JCTGF zwalnia nas z potrzeby posiadania obiektu (egzemplarza klasy) w celu zapytania klasy „Jak się nazywasz?” Jeśli klasa jest nazwana jako 2TQRGTV[/QFKHKGTU, mo emy wywołać jej metodę )GV pisząc 2TQRGTV[/QFKHKGTU0COG. Właściwość 0COG w powy szym fragmencie pokazuje bardzo istotną ró nicę między Vi- sual Basic .NET a VB6. Właściwość ta jest bardzo sprecyzowana w swoich zamierze- niach — Visual Basic .NET umo liwia nam określenie swoich zamiarów co do właści- wości i wprowadzenie ich w ycie za pomocą bardzo precyzyjnej gramatyki języka. W VB6 mogliśmy zdefiniować właściwość tylko do odczytu poprzez instrukcję .GV 2TQRGTV[, lecz jej status tylko-do-odczytu był ukryty. Poza tym, nie mogliśmy definio- wać składowych 5JCTGF. Oczywiście mo na dyskutować, czy tak niewielkie zmiany semantyczne w języku rze- czywiście są istotne. Odpowiedź brzmi: „Są jak najbardziej istotne”. Programowanie jest niemal tak samo precyzyjne jak matematyka, a języki, w których programujemy, powinny być ekspresyjne w sposób umo liwiający uniknięcie tworzenia niejednoznacz- nego, głupiego i nadmiarowego kodu. Niuanse i subtelność w wyra aniu się powinny być pozostawione kochankom i mę om stanu. &QFCYCPKG CVT[DWVÎY Y C EKYQ EK Atrybuty nie są całkowicie nowym zagadnieniem w Visual Basic .NET. Mogłeś się z nimi spotkać ju w VB6. Na przykład otwórz w edytorze tekstu moduł klasy VB6 — plik .CLS — i zmień wartość atrybutu #VVTKDWVG 8$A2TGFGENCTGF+&  (CNUG na #VVTKDWVG 8$A2TGFGENCTGF+&  6TWG, a w rezultacie otrzymasz klasę utworzoną automatycznie. Jeśli klasa ma nazwę %NCUU, a jej metoda (QQ, to po powy szej modyfikacji napisanie %NCUU (QQ powinno uruchomić kod klasy. Dzieje się tak dlatego, gdy atrybut 8$A2TGFGENCTGF+& jest mechanizmem, który sprawia, e formularze tworzą się automatycznie.
    • 254 Część II Zaawansowane programowanie zorientowane obiektowo No dobrze, dlaczego więc ten temat jest poruszany w ksią ce o Visual Basic .NET? Atrybuty są istotne, gdy stanowią pełnoprawny aspekt tworzenia aplikacji w VB .NET. Zostały równie znacząco zmodyfikowane i ulepszone w stosunku do atrybutów zna- nych z VB6. Wykorzystaj właściwość 0COG z poprzedniego podrozdziału do sprawdze- nia działania jednego z atrybutów: 2WDNKE 5JCTGF 4GCF1PN[ 2TQRGTV[ 0COG #U 5VTKPI 5[UVGO&KCIPQUVKEU&GDWIIGT*KFFGP )GV 4GVWTP 2TQRGTV[/QFKHKGTU 'PF )GV 'PF 2TQRGTV[ Zwróć uwagę na wykorzystanie atrybutu w metodzie )GV. (Atrybut &GDWIIGT*KFFGP, nale- ący do klasy atrybutów z przestrzeni nazw 5[UVGO&KCIPQUVKEU, był omawiany w roz- dziale 1., „Ujednolicone środowisko pracy Visual Studio”). Zapobiega on wchodzeniu przez debuger do wnętrza tej metody. Atrybuty mogą mieć zastosowanie w bardzo wielu miejscach w Visual Basic .NET. Na przykład korzystasz ze znacznika atrybutu przy konwersji metody do metody 9GD. Być mo e atrybuty zakończą swój ywot tak, jak szybkie samochody kończą go w rękach nastoletnich kierowców, jednak są one całkowicie odmienione w Visual Basic .NET i ich omówienie wymaga osobnego rozdziału. W tej chwili musisz jedynie wiedzieć, e jeśli znajdziesz znacznik PCOG w kodzie VB .NET, to jest to atrybut. W rozdziale 12., „Definiowanie atrybutów”, znajdziesz szczegółowe omówienie atrybutów. &QFCYCPKG OGVQF FQ MNCU Metody są to funkcje i procedury, które nale ą do klasy lub struktury. Poniewa struktury zostały szczegółowo omówione w rozdziale 5., „Procedury, funkcje i struktury”, wszyst- kie nasze kolejne przykłady będą się opierać na klasach. Cokolwiek jest mo liwe do zrobienia z procedurą w module, to samo mo esz uczynić z procedurą w klasie. Jedyną zasadą w przypadku metod jest kierowanie się z wyczu- ciem własnymi upodobaniami w trakcie pisania kodu. Osobiście lubię muzykę Beet- hovena i kapelę rockową Creed, więc prawdopodobnie moje upodobania ró nią się od Twoich. Czy kwestia indywidualnych upodobań w przypadku programowania jest rze- czą istotną? I tak, i nie. Jeśli jesteś programistą, mo esz robić i tworzyć, co tylko Ci przyjdzie do głowy. Jeśli w dodatku nie dostajesz pieniędzy za kod, który piszesz, mo esz puścić wodze fantazji i czynić prawdziwe cuda w swoich aplikacjach. Jednak e istnieje kilkanaście dobrych pozycji ksią kowych omawiających zasady dotyczące dobrego stylu w programowaniu. Jedną z ostatnio wydanych ksią ek na ten temat jest pozycja Martina Fowlera traktująca o refaktoringu. Świetne ksią ki o programowaniu obiektowym napisali tak e Grady Bo- och, James Coplien i Bjarne Stroustrup. Do niektórych z tych pozycji znajdziesz odno- śniki w literaturze do tej ksią ki. Większość z przykładów prezentowanych w tej ksią ce jest napisana z zastosowaniem w pewnym stopniu zasad refaktoringu. Wa niejszą rzeczą jest jednak to, e programuję
    • Rozdział 7. Tworzenie klas 255 w ten sposób od ponad 12 lat. Swoje aplikacje piszę takim stylem z bardzo prostego po- wodu: po ponad 10 latach programowania w sześciu językach i napisania milionów wier- szy kodu mój osobisty styl pozwala na tworzenie kodu o bardzo niewielkich rozmiarach, który mo e być wielokrotnie wykorzystywany, a przy tym jest łatwy do utrzymania i jest szybki. W tym miejscu chciałbym zaproponować kilka wskazówek, z których korzystam podczas implementowania metod. Staraj się tworzyć niewielki interfejs publiczny. Parafrazując Boocha (1995), implementuj garść metod i właściwości publicznych. Staraj się trafnie nazywać metody, unikając niestandardowych skrótów. W nazwie metody stosuj czasownik, rzeczownik pozostawiając opisowi właściwości. Niech Twoje metody wykonują działanie ściśle odpowiadające ich nazwie; przyjmij zasadę: jedna metoda, jedno działanie. Nie twórz metod, które wykonują na raz zbyt wiele czynności. Ograniczaj metody do około pięciu wierszy kodu, a na pewno nigdy ponad to, co mo esz za jednym razem zobaczyć na ekranie. Korzystaj z techniki refaktoringu „Wydzielanie metod”, dając nowym metodom trafne nazwy zamiast pisania długich komentarzy. Rozwa zaimplementowanie wszystkich niepublicznych metod jako chronionych i wirtualnych — nigdy nie wiesz, kto będzie chciał do nich w przyszłości zaglądać. Zasady te nie powstały w ciągu jednego dnia. Są one efektem naśladowania mistrzów programowania przez dłu szy czas. Stosowanie niektórych z nich — jak na przykład tworzenia krótkich, pojedynczych metod — zawsze wydawało się logiczne. Na koniec opowiem krótką historyjkę, ilustrującą sens stosowania się do wskazówek. Swój pierwszy samochód kupiłem za 325 dolarów w wieku 15 lat. Było to w dniu, w którym uzyskałem na to pozwolenie mojego nauczyciela. Samochód ten można było nazwać „toczącym się wrakiem”. Nic w tym samochodzie nie było pięknego poza faktem, że potrafił jechać do przodu. Każde z kół miało inny rozmiar, dziura w chłodnicy była wielkości piłki do footballu, skrzynia biegów nie do końca chciała działać poprawnie, a regulacja położenia siedzenia kierowcy nie miała sprawnej blokady. Gdy samochód się zatrzymywał, siedzenie jechało do przodu; gdy ruszałem, siedzenie ślizgało się do tyłu. Krótko po kupieniu auta podjąłem decyzję o rozpoczęciu prac renowacyjnych. Remont rozpocząłem od naprawy paska napędzającego wentylator chłodnicy. Od ojca pożyczyłem narzędzia i zacząłem naprawę od usunięcia wentylatora, a następnie pompy wodnej. Prawdopodobnie wyjąłbym też blok silnika, gdybym tylko wiedział, jak to zrobić — wszystko po to, aby wymienić pasek. Po kilku godzinach walki poddałem się. Śrubki, które znalazłem, wkręciłem z powrotem do silnika i zaprowadziłem samochód do zakładu. Mechanik poluzował alternator, luzując tym samym naciąg starego paska, zdjął ten pasek, założył nowy, po czym naciągnął go odpowiednio dokręcając śruby alternatora. Za 5 minut pracy skasował 35 dolców. Całkiem nieźle, jak na 5 minut. Zarobił 35 dolarów, jednak nie za to, że jego praca była ciężka, ale za to, że wiedział, jak ją zrobić. (No dobra, część tej historyjki zapożyczyłem ze starej bajki). Morał z tej historii jest taki, że dokładna wiedza na temat, jak i dlaczego należy coś zrobić, jest jedynym usprawiedliwieniem na odchodzenie od ogólnie przyjętych zasad. Kod jest rzeczą tak osobistą, jak każda inna działalność twórcza. Przestrzeganie w przypadkach ogólnych dobrych zasad zwiększy Twoją produktywność; nieprzestrzeganie ich — udoskonali Twój talent.
    • 256 Część II Zaawansowane programowanie zorientowane obiektowo +ORNGOGPVQYCPKG MQPUVTWMVQTÎY K FGUVTWMVQTÎY Istnieją dwie specjalne metody, które będziesz musiał implementować. Określa się je mianem konstruktora i destruktora. Konstruktor jest wywoływany do inicjowania klasy, destruktor — do deinicjowania lub finalizacji klasy. W Visual Basic .NET konstruktor implementowany jest jako 5WD 0GY, a destruktor występuje jako chroniona metoda 5WD (KPCNKG. Ka da klasa otrzymuje przynajmniej jednego konstruktora, odziedziczonego z klasy ba- zowej 1DLGEV. 1DLGEV definiuje procedurę bez parametrów 5WD 0GY, która jest wywoły- wana, gdy piszesz kod jak poni ej: &KO OKGPPCQDKGMVQYC #U 0GY PCYCMNCU[ OKGPPCQDKGMVQYC jest dowolną poprawną nazwą zmiennej, a PCYCMNCU[ reprezentuje jakikolwiek poprawny typ referencyjny. Z powy szej instrukcji mo na wywnioskować, e 0GY wygląda jak operator, jednak po prześledzeniu kilku kolejnych przykładów zoba- czysz, e taka instrukcja prowadzi bezpośrednio do metody 5WD 0GY . Metoda New — czyli konstruktor — jest wywoływana, gdy tworzysz nowe egzemplarze klas. Gdy obiekt jest usuwany z pamięci, systemowy odzyskiwacz pamięci (garbage collector) wywołuje metodę 5WD (KPCNKG, czyli destruktora. Mo esz zaimplementować destruktora w celu deinicjalizacji obiektów poprzez dodanie metody (KPCNKG do swoich klas: 2TQVGEVGF 1XGTTKFGU 5WD (KPCNKG 'PF 5WD Mechanizm odzyskiwania pamięci często występuje jako skrót GC. GC jest również przestrzenią nazw zawierającą systemowy odzyskiwacz pamięci. Tradycyjnie, celem destruktora jest zwolnienie pamięci przypisanej obiektom zawartym w klasie. Poniewa Visual Basic .NET zatrudnia GC, nie mo esz być pewien, kiedy do- kładnie GC wywoła Twojego destruktora. Ciągle mo esz korzystać z destruktora, aby usunąć obiekty ze swojej klasy, jeśli jednak posiadasz zasoby wra liwe na czas, które muszą być zwolnione natychmiast, dodaj publiczną metodę &KURQUG. W kolejnych przy- kładach będziemy korzystali z 2WDNKE 5WD &KURQUG w celu wykonania porządków ty- pu zamykanie plików czy zestawów rekordów. &GHKPKQYCPKG MQPUVTWMVQTÎY Agregacja jest pojęciem określającym dodawanie składowych do klas. Gdy dana klasa posiada składowe, które równie są klasami, przy czym bierze ona jednocześnie odpo- wiedzialność za tworzenie i niszczenie egzemplarzy tych składowych, to o takim po- wiązaniu mówimy, e jest to agregacja. Natomiast gdy klasa posiada składowe będące klasami, ale ich tworzeniem i usuwaniem zajmuje się jakaś jednostka z zewnątrz, to mówimy wówczas o związku. Gdy definiujesz agregacje w swojej klasie, musisz utwo- rzyć dla niej konstruktora. Powód tworzenia konstruktora mo e być dowolny, jednak jeśli będziesz chciał two- rzyć egzemplarze składowych agregacyjnych, to konstruktor jest niezbędny. Domyślny
    • Rozdział 7. Tworzenie klas 257 konstruktor jest reprezentowany przez 5WD 0GY i nie posiada parametrów. W celu jego zaprezentowania zdefiniowałem klasę .QCFGT%NCUU, która wykorzystuje klasę 5[UVGO +16GZV4GCFGT do załadowania pliku tekstowego do #TTC[.KUV. 2WDNKE 5WD 0GY /[$CUG0GY (#TTC[.KUV  0GY #TTC[.KUV 'PF 5WD Kod będzie poprawny również wówczas, gdy usuniemy instrukcję /[$CUG0GY . Semantycznie, wszystkie klasy pochodne muszą wywoływać konstruktora macierzystego, jednak wygląda na to, że Visual Basic .NET w większości przypadków robi to za Ciebie. Zamiast zgadywania, kiedy i dlaczego VB .NET wywołuje konstruktora klasy bazowej, zawsze umieszczaj /[$CUG0GY jako pierwszą instrukcję w swoim konstruktorze. Jeśli zechcesz wywołać konstruktora parametrycznego w klasie potomnej, zamień po prostu wywołanie zwykłego konstruktora na wywołanie konstruktora parametrycznego. Nie posiadające parametrów 5WD 0GY wywołuje konstruktora klasy bazowej za po- mocą instrukcji /[$CUG0GY . /[$CUG jest słowem zarezerwowanym, które umo liwia odwoływanie się do składowych w klasie bazowej danej klasy, zwanej tak e klasą macierzystą. Pamięcią wewnętrzną dla .QCFGT%NCUU jest #TTC[.KUV. Poniewa .QC FGT%NCUU — którego konstruktor jest pokazany — jest w posiadaniu #TTC[.KUV , z tego względu konstruktor tworzy egzemplarz #TTC[.KUV, zanim cokolwiek innego zostanie wykonane. &GHKPKQYCPKG RTGEKæ QP[EJ MQPUVTWMVQTÎY RCTCOGVT[EP[EJ Jeśli w celu poprawnej inicjalizacji musisz przekazać do swojej klasy dane z zewnątrz, mo esz zdefiniować konstruktora parametrycznego. .QCFGT%NCUU słu y do załadowana pliku tekstowego do #TTC[.KUV. Wydaje się oczywi- ste, e nale ałoby zainicjować obiekty .QCFGT%NCUU nazwą ładowanego pliku. Mając dwa konstruktory, mo emy tworzyć egzemplarze bez znajomości nazwy pliku oraz gdy tę nazwę znamy: 2WDNKE 5WD 0GY $[8CN #(KNG0COG #U 5VTKPI /G0GY (KNG0COG  #(KNG0COG 'PF 5WD Aby uniknąć powielania kodu, wydelegujemy część odpowiedzialną za konstrukcję kla- sy do bezparametrycznego konstruktora z /G0GY i przechowamy parametr w pamięci podręcznej. Posiadanie w tej samej klasie dwóch metod 5WD 0GY oznacza, e konstruktor został przecią ony. Konstruktory nie zezwalają na u ycie słowa kluczowego 1XGTNQCFU. Jest to specjalna zasada wprowadzona dla konstruktorów przez in ynierów Visual Basic .NET. (Więcej na temat metod przecią onych znajdziesz w podrozdziale „Korzystanie z mo- dyfikatorów”).
    • 258 Część II Zaawansowane programowanie zorientowane obiektowo +ORNGOGPVQYCPKG FGUVTWMVQTÎY Jeśli przypisujesz pamięć w momencie wywołania konstruktora, musisz równie zwolnić ją, implementując do tego celu destruktora. 5WD 0GY jest u ywany podobnie jak %NCUUA +PKVKCNKG w VB6, a 5WD (KPCNKG w sposób analogiczny do %NCUUA6GTOKPCVG. Obiekty utworzone przez konstruktora muszą być usunięte za pomocą destruktora. Generalnie, jeśli w Twojej klasie nie ma zdefiniowanego konstruktora, prawdopodobnie równie nie potrzebujesz destruktora. Oto podstawowa forma, w jakiej występuje de- struktor (KPCNKG, zaimplementowana w przykładowej klasie .QCFGT%NCUU: 2TQVGEVGF 1XGTTKFGU 5WD (KPCNKG &KURQUG 'PF 5WD Implementując destruktora na podstawie metody &KURQUG, mo esz bezpośrednio zwal- niać obiekty za pomocą tej metody, jeszcze zanim uczyni to GC. Istnieją określone za- sady i reguły dotyczące zwalniania zasobów — więcej informacji na ten temat znaj- dziesz w następnym podrozdziale. Destruktor (KPCNKG jest chroniony (2TQVGEVGF); z tego względu, nie mo esz go bezpo- średnio wywołać — jest on wywoływany przez GC. Oto podstawowe zasady obowią- zujące przy implementacji destruktora: Metody (KPCNKG powodują obcią enie systemu. Nie definiuj przecią onej metody (KPCNKG, jeśli nie jest to konieczne. Nie definiuj metody (KPCNKG jako publicznej. Zwalniaj posiadane obiekty za pomocą metody &KURQUG ; korzystaj z (KPCNKG wywołując &KURQUG. Nie likwiduj referencji w swoim destruktorze; jeśli Twój kod nie utworzył obiektu, jest to referencja, a nie agregacja. Nie twórz obiektów ani nie korzystaj z innych obiektów w metodzie (KPCNKG; destruktory słu ą wyłącznie do czyszczenia pamięci i zwalniania zasobów. W metodzie (KPCNKG jako pierwszą instrukcję zawsze stosuj /[$CUG(KPCNKG. Ze względu na to, e nie wiemy, kiedy GC zwalnia obiekty, mo na zaimplementować metodę 2WDNKE &KURQUG i wywoływać ją jawnie w bloku ochrony zasobów (KPCNN[; dzięki temu uzyskamy konkretną finalizację obiektów takich jak np. strumienie danych czy wątki. +ORNGOGPVQYCPKG OGVQF[ &KURQUG Destruktory są chronione. Konsumenci nie mogą i nie powinni mieć mo liwości bezpo- średniego wywoływania metody (KPCNKG. Mo esz jawnie uruchomić systemowy odzy- skiwacz pamięci za pomocą instrukcji 5[UVGO)%%QNNGEV, lecz nie jest to zalecana praktyka i powoduje znaczne obcią enie systemu.
    • Rozdział 7. Tworzenie klas 259 Jeśli chcesz wyczyścić znaczące obiekty, zastosuj metodę 2WDNKE &KURQUG i ją wywołaj. Oto kilka po ytecznych wskazówek dotyczących implementacji metody &KURQUG: Dodawaj metodę &KURQUG, wykorzystując interfejs +&KURQUCDNG. (+&KURQUCDNG posiada jedną metodę, &KURQUG, a w systemie pomocy Visual Studio .NET znajdziesz przykłady klas z zaimplementowanym tym interfejsem). Jeśli posiadasz istotne zasoby, takie jak uchwyty Windows, zestawy rekordów lub strumienie plików, które muszą być zwolnione do systemu zaraz po zakończeniu korzystania z nich, wówczas utwórz publiczną metodę &KURQUG. Zaprojektuj mechanizm powstrzymujący usuwanie, jeśli u ytkownik bezpośrednio wywoła metodę &KURQUG. Jeśli klasa bazowa implementuje +&KURQUCDNG, wywołaj metodę &KURQUG z klasy bazowej. Zaimplementuj metodę (KPCNKG, która wywoła &KURQUG. W ten sposób upewnisz się, e &KURQUG będzie zawsze wywoływana. Zwalniaj posiadane obiekty w metodzie &KURQUG. Rozwa mo liwość wygenerowania wyjątku 1DLGEV&KURQUGF'ZEGRVKQP, w przypadku gdy konsument próbuje skorzystać z obiektu po wcześniejszym wywołaniu metody &KURQUG. W swojej metodzie &KURQUG wywołaj )%5WRRTGUU(KPCNKG /G aby powiedzieć GC, e nie musi uruchamiać metody (KPCNKG. Zezwól na wywoływanie obiektu &KURQUG więcej ni jeden raz. Drugie i kolejne wywołania nie powinny wykonywać adnych operacji. Przy wykorzystaniu tych wskazówek poni ej została utworzona metoda &KURQUG dla .QCFGT%NCUU: 2WDNKE 5WD &KURQUG +ORNGOGPVU +&KURQUCDNG&KURQUG 5VCVKE (&KURQUGF #U $QQNGCP  (CNUG +H (&KURQUGF 6JGP 'ZKV 5WD (&KURQUGF  6TWG %NQUG (#TTC[.KUV  0QVJKPI )%5WRRTGUU(KPCNKG /G 'PF 5WD Metoda &KURQUG implementuje +&KURQUCDNG&KURQUG (przez to wiemy, e +ORNGOGPVU +&KURQUCDNG jest zawarte w naszym .QCFGT%NCUU). Lokalna zmienna statyczna jest wy- korzystana w celu umo liwienia bezpiecznego wywoływania &KURQUG więcej ni jeden raz. Druga instrukcja ustawia odpowiednią wartość $QQNGCP, wskazując, e &KURQUGF była ju wywołana. Metoda .QCFGT%NCUU%NQUG jest wywoływana w celu zamknięcia 6GZV4GCFGT, co nie zostało jeszcze pokazane, a #TTC[.KUV zostaje przypisany 0QVJKPI. Na końcu, )%5WRRTGUU(KPCNKG informuje GC, e nie ma potrzeby wywoływania me- tody (KPCNKG dla danego obiektu.
    • 260 Część II Zaawansowane programowanie zorientowane obiektowo 5RGELCNPG U QYC MNWEQYG Podczas dyskusji o klasach zauwa yłeś pewnie częste korzystanie z dwóch specyficz- nych słów kluczowych — /[$CUG oraz /[%NCUU. /[$CUG, jak ju widziałeś, zezwala na wywoływanie metod w klasie bazowej tworzonej klasy, które mogą być przecią ane; rozwiązuje to problem niejednoznaczności klas. /[%NCUU jest przybli onym odpowiednikiem referencji do samej siebie /G. /[%NCUU za- kłada, e jakiekolwiek metody wywołane z niej są zadeklarowane jako 0QV1XGTTKFCDNG. /[%NCUU wywołuje metodę, nie biorąc pod uwagę typu obiektu, jaki posiada on w trakcie działania aplikacji, efektywnie omijając polimorficzne zachowanie. Ze względu na to, e /[%NCUU jest referencją do obiektu, nie mo esz z niej korzystać w metodach 5JCTGF. Referencja do siebie /G została przeniesiona do Visual Basic .NET. /G do działania wy- maga egzemplarza. /[%NCUU wywołuje metodę w tej samej klasie, natomiast /G wywołuje metodę w obiekcie przypisanym przez /G, to znaczy, w sposób polimorficzny. Przyjrzyj się następującym klasom. 2WDNKE %NCUU %NCUU 2WDNKE 1XGTTKFCDNG 5WD 2TQE 'PF 5WD 2WDNKE 5WD 0GY /G2TQE 'PF 5WD 'PF %NCUU 2WDNKE %NCUU %NCUU +PJGTKVU %NCUU 2WDNKE 1XGTTKFGU 5WD 2TQE 'PF 5WD 'PF %NCUU Gdy tworzony jest obiekt typu %NCUU, konstruktor w %NCUU wywołuje %NCUU2TQE. Jeśli /G2TQE zamienimy na /[%NCUU2TQE, wówczas wywołana będzie %NCUU2TQE. &QFCYCPKG HWPMELK K RTQEGFWT FQ OGVQF Metody są to funkcje i procedury, które zdefiniowane zostały w ramach klasy lub struk- tury. Jedynym wyzwaniem, które pojawia się podczas implementacji metod, jest opra- cowanie odpowiednich algorytmów rozwiązujących dany problem, napisanie dla nich jak najprostszego kodu oraz określenie dostępu do tworzonych metod wraz z u yciem odpowiednich modyfikatorów, które byłyby dla nich najbardziej odpowiednie. Niestety, sposób definiowania metod jest zagadnieniem bardzo subiektywnym. Najlep- szym sposobem na nauczenie się implementowania metod jest analizowanie i pisanie jak największej ilości kodu, a następnie wybranie stylu naszym zdaniem najlepszego. Nie bój się eksperymentować i zmieniać kod ju napisany. Wydruk 7.6 przedstawia kompletną klasę .QCFGT%NCUU.
    • Rozdział 7. Tworzenie klas 261 9[FTWM  Zawartość klasy LoaderClass  +ORQTVU 5[UVGO+1   2WDNKE %NCUU .QCFGT%NCUU  +ORNGOGPVU +&KURQUCDNG   2TKXCVG ((KNG0COG #U 5VTKPI  2TKXCVG (4GCFGT #U 6GZV4GCFGT  2TKXCVG (#TTC[.KUV #U #TTC[.KUV  2WDNKE 'XGPV 1P6GZV $[8CN 6GZV #U 5VTKPI   2TKXCVG 5WD &Q6GZV $[8CN 6GZV #U 5VTKPI  4CKUG'XGPV 1P6GZV 6GZV  'PF 5WD   2WDNKE 2TQRGTV[ (KNG0COG #U 5VTKPI  )GV  4GVWTP ((KNG0COG  'PF )GV  5GV $[8CN 8CNWG #U 5VTKPI  ((KNG0COG  8CNWG  'PF 5GV  'PF 2TQRGTV[   2WDNKE 1XGTNQCFU 5WD 1RGP  +H (4GCFGT +U 0QVJKPI 6JGP  (4GCFGT  (KNG1RGP6GZV ((KNG0COG  'NUG  6JTQY 0GY #RRNKECVKQP'ZEGRVKQP HKNG KU CNTGCF[ QRGP  'PF +H  'PF 5WD   2WDNKE 1XGTNQCFU 5WD 1RGP $[8CN #(KNG0COG #U 5VTKPI  (KNG0COG  #(KNG0COG  1RGP  'PF 5WD   2WDNKE 5WD %NQUG  +H (4GCFGT +U 0QVJKPI 6JGP 'ZKV 5WD  (4GCFGT%NQUG  (4GCFGT  0QVJKPI  'PF 5WD   2TKXCVG (WPEVKQP #FF $[8CN 6GZV #U 5VTKPI #U $QQNGCP  +H 6GZV  6JGP 4GVWTP (CNUG  &Q6GZV 6GZV  (#TTC[.KUV#FF 6GZV  4GVWTP 6TWG  'PF (WPEVKQP   2TKXCVG (WPEVKQP 4GCFKPI #U $QQNGCP  4GVWTP 0QV (&KURQUGF #PF#NUQ #FF (4GCFGT4GCF.KPG  'PF (WPEVKQP   2WDNKE 5WD .QCF  9JKNG 4GCFKPI  #RRNKECVKQP&Q'XGPVU  'PF 9JKNG
    • 262 Część II Zaawansowane programowanie zorientowane obiektowo  'PF 5WD   2WDNKE 5WD 0GY  /[$CUG0GY  (#TTC[.KUV  0GY #TTC[.KUV  'PF 5WD   2WDNKE 5WD 0GY $[8CN #(KNG0COG #U 5VTKPI  /G0GY  (KNG0COG  #(KNG0COG  'PF 5WD   2TKXCVG (&KURQUGF #U $QQNGCP  (CNUG   2WDNKE 5WD &KURQUG +ORNGOGPVU +&KURQUCDNG&KURQUG  +H (&KURQUGF 6JGP 'ZKV 5WD  (&KURQUGF  6TWG  %NQUG  (#TTC[.KUV  0QVJKPI  'PF 5WD   2TQVGEVGF 1XGTTKFGU 5WD (KPCNKG  &KURQUG  /[$CUG(KPCNKG  'PF 5WD   2WDNKE 5JCTGF (WPEVKQP .QCF $[8CN #(KNG0COG A  #U 5VTKPI #U .QCFGT%NCUU   &KO #.QCFGT #U 0GY .QCFGT%NCUU #(KNG0COG  #.QCFGT1RGP  #.QCFGT.QCF  4GVWTP #.QCFGT   'PF (WPEVKQP  'PF %NCUU Klasa .QCFGT%NCUU definiuje metodę &Q6GZV, dwie metody 1RGP oraz %NQUG, #FF, 4GCFKPI i .QCF. &Q6GZV jest metodą prywatną; jej zadanie polega na wygenerowaniu zdarzenia w celu poinformowania o jakichkolwiek obiektach, które mogą chcieć podsłuchać pro- ces ładowania. Obie metody 1RGP są publiczne; zostały zdefiniowane z modyfikatorami 1XGTNQCFU, aby umo liwić konsumentom otwieranie pliku z przekazaniem jego nazwy w argumencie metody lub bez tego argumentu, zakładając w takim przypadku, e nazwa pliku została wcześniej przypisana w wywołaniu konstruktora lub poprzez modyfikację wartości właściwości. (Właściwość (KNG0COG jest zdefiniowana w wierszach 15. – 22.). Metoda #FF eliminuje potrzebę istnienia zmiennej tymczasowej. Mo emy przekazać wynik metody 6GZV4GCFGT4GCF.KPG jako parametr do #FF, która zwróci nam $QQNGCP wskazujący, czy chcemy wartość czy nie. Funkcja 4GCFKPI zwraca wartość $QQNGCP określającą, e dodaliśmy tekst i e nie wywołaliśmy metody &KURQUG (wiersze 50. – 52.). Przy okazji w wierszu 51. widzimy przykład zastosowania operatora działania skróconego #PF#NUQ. Jeśli metoda &KURQUG została wywołana, 0QV &KURQUGF zostaje skrócona; w przeciwnym razie zostaje odczytywany następny wiersz tekstu. Jeśli (4G CFGT4GCF.KPG dojdzie do końca pliku, metoda 4GCF.KPG zwróci pusty ciąg ( ), a 4G CFKPI zwróci (CNUG. Poniewa rozdzieliliśmy działanie 4GCFKPI i #FF, metoda .QCF jest bardzo prosta i składa się jedynie z pętli 9JKNG (wiersze 54. – 58.).
    • Rozdział 7. Tworzenie klas 263 Jedynymi metodami publicznymi w naszej klasie są 1RGP, %NQUG i 4GCF. Z tego względu klasa jest bardzo łatwa do obsługi przez konsumentów. Pozostałe metody wspomagają działanie metod publicznych i nie muszą być prezentowane u ytkownikom, a tym bar- dziej przez nich wywoływane. Są one więc prywatne. Porównaj pojedynczego muzyka z orkiestrą. Jeśli masz jednego muzyka, który gra na jednym instrumencie, rodzaj muzyki przez niego prezentowany jest siłą rzeczy ograniczony. Jeśli natomiast posiadasz całą orkiestrę z kilkudziesięcioosobowym składem, ich możliwości i różnorodność muzyki przez nich granej są nieporównywalnie większe. Monolityczne metody są jak samotny muzyk; przyjemne, lecz niezbyt różnorodne. Wiele pojedynczych metod — myśląc o konstruktorach przeciążonych w roli sekcji dętej — oznacza, że każda metoda może się w czymś specjalizować i być wykorzystywana bardziej różnorodnie. W naszym konkretnym przykładzie prawdopodobnie nie wykorzystamy ponownie metod #FF, 4GCFKPI czy &Q6GZV. To, co uzyskujesz dzięki pojedynczym funkcjom, to łatwość ich implementacji oraz małe prawdopodobieństwo, e z ich powodu wystąpią jakieś błędy. Kolejną zaletą, mo e nie ju tak oczywistą, jest to, e takie metody mogą być przecią- ane w podklasach. (Jeśli chciałbyś rozszerzyć na podklasę prywatne metody .QCFGT %NCUU, musiałbyś zmienić je na chronione, co z drugiej strony jest czynnością trywialną). Jeśli natomiast będziesz korzystał z mniejszej liczby monolitycznych metod, będziesz miał mniej mo liwości do ich przecią ania czy rozszerzania działalności. -QT[UVCPKG OQF[HKMCVQTÎY OGVQF Modyfikatory metod pozwalają nam na uzyskanie większej kontroli nad ich implemen- tacjami. 2TGEKæ CPKG OGVQF Modyfikator 1XGTNQCFU jest wykorzystywany do wskazania, e w danej klasie dwie lub więcej metod jest przecią onych. Przykładem przecią onej metody jest .QCFGT%NCUU1RGP. Dzięki przecią aniu mo liwa jest implementacja metod, które wykonują semantycznie tę samą operację, ale ró nią się liczbą lub typem argumentów. Weźmy dla przykładu metodę, która wypisuje tekst na konsolę, 2TKPV. Bez przecią ania musielibyśmy wpro- wadzić unikalne nazwy dla metod wypisujących poszczególne typy, na przykład 2TKPV +PVGIGT, 2TKPV5VTKPI, 2TKPV&CVG. Takie podejście wymagałoby od u ytkowników na- uczenia się nazw wielu metod, które wykonują to samo zadanie. Dzięki przecią aniu wszystkie powy sze metody mogą nazywać się 2TKPV, a kompilator, na podstawie typu argumentu, sam wywoływałby odpowiednią metodę; pozostawmy więc wykonywanie nudnych zadań kompilatorowi, a sami zajmijmy się bardziej istotniejszymi sprawami. Nagłówek procedury, liczba i typ argumentów oraz typ zwracany (jeśli procedura jest funkcją) tworzą wspólnie sygnaturę procedury. Również właściwości mogą być przeciążane.
    • 264 Część II Zaawansowane programowanie zorientowane obiektowo Oto podstawowe wskazówki dotyczące u ywania modyfikatora 1XGTNQCFU: Jeśli w Twoim kodzie występują metody przecią one, u ycie słowa 1XGTNQCFU jest niezbędne (na wydruku 7.6 mo esz sprawdzić, w którym miejscu nale y je stosować). Metody przecią one muszą posiadać ró ną liczbę lub typ parametrów (Visual Basic .NET umo liwia przecią anie metod z bardzo podobnymi typami, jak np. .QPI i +PVGIGT). Nie mo na przecią ać metod, zmieniając jedynie modyfikator dostępu, np. 5JCTGF. Nie mo na przecią ać metod, zmieniając tylko rodzaj przekazywanych argumentów ($[8CN i $[4GH) Nie mo esz przecią ać metod, zmieniając wyłącznie nazwy parametrów, a pozostawiając takie same typy. Nie mo esz przecią ać metod, modyfikując jedynie typ zwracany przez metodę, jednak oczywiście mogą istnieć dwie metody przecią one ró niące się typem zwracanej wartości. Na przykład, nie mogą być przecią one procedura i funkcja o takich samych nazwach i argumentach, nie jest to równie mo liwe w przypadku dwóch funkcji z takimi samymi argumentami, które ró nią się jedynie typem zwracanej wartości. Jeśli znajdziesz się w sytuacji, gdy wykonywana operacja jest taka sama, a ró ni się typ danych, wówczas potrzebujesz metody przecią onej. Gdy natomiast implementujesz dwie metody o takim samym kodzie, które ró nią się jedynie wartością jednego lub kil- ku parametrów, zastosuj pojedynczą metodę z parametrem 1RVKQPCN. 2TGU CPKCPKG OGVQF Modyfikator 1XGTTKFGU umo liwia polimorfizm. U ywasz go, gdy chcesz rozszerzyć lub zmodyfikować zachowanie się metody w klasie bazowej. Metoda klasy bazowej musi mieć taką samą sygnaturę jak metoda ją przesłaniająca. Do modyfikatora 1XGTTKFGU powrócimy w rozdziale 10., „Dziedziczenie i polimorfizm”. /QF[HKMCVQT[ 1XGTTKFCDNG /WUV1XGTTKFG K 0QV1XGTTKFCDNG Modyfikatory 1XGTTKFCDNG, /WUV1XGTTKFG i 0QV1XGTTKFCDNG są u ywane do obsługi me- tod, które mogą być przesłaniane i które muszą być przesłaniane. 1XGTTKFCDNG i 0QV1XGTTKFCDNG wzajemnie się wykluczają. Pierwszy z modyfikatorów, 1XGTTKFCDNG, wskazuje, e metoda mo e być przesłonięta. 0QV1XGTTKFCDNG przy nazwie metody oznacza, e nie mo esz jej przesłaniać. /WUV1XGTTKFG wskazuje, e metoda jest abstrakcyjna, a klasy potomne muszą implementować tego typu metody w klasie macie- rzystej. Z /WUV1XGTTKFG wynika jednoznacznie, e metoda jest przesłanialna, nie ma więc potrzeby stosowania w niej modyfikatora 1XGTTKFCDNG, a obecność 0QV1XGTTKFCDNG w metodzie /WUV1XGTTKFG nie ma adnego sensu.
    • Rozdział 7. Tworzenie klas 265 Metody /WUV1XGTTKFG nie posiadają implementacji w klasie, w której zostały z takim modyfikatorem zadeklarowane. Metody te są odpowiednikiem czysto wirtualnych me- tod w C++ i wirtualnych metod abstrakcyjnych w Object Pascal; potomkowie muszą ta- kie metody implementować. -QT[UVCPKG OQF[HKMCVQTC 5JCFQYU Jeśli chcesz, aby klasa potomna mogła korzystać z nazwy poprzednio wprowadzonej w klasie nadrzędnej, skorzystaj ze słowa 5JCFQYU. Nazwy zakryte nie są usuwane z kla- sy macierzystej; słowo 5JCFQYU zezwala po prostu na powtórne wprowadzenie w klasie potomnej poprzednio u ytej nazwy bez wystąpienia błędu kompilacji. Składowe w klasie potomnej nie muszą być tego samego typu jak składowe zakryte; dwie składowe muszą mieć jedynie identyczne nazwy. Jakakolwiek składowa w klasie potomnej mo e zakryć dowolną składową klasy nadrzędnej. Metoda w klasie potomnej mo e zakryć pole, właściwość, metodę lub zdarzenie klasy nadrzędnej. Poni szy frag- ment demonstruje wykorzystanie modyfikatora 5JCFQYU do ponownego wprowadzenia metody w klasie potomnej z taką samą nazwą jak metoda w klasie nadrzędnej. 2WDNKE %NCUU # 2WDNKE 5WD (QQ 'PF 5WD 'PF %NCUU 2WDNKE %NCUU $ +PJGTKVU # 2WDNKE 5JCFQYU 5WD (QQ 'PF 5WD 'PF %NCUU Wydruk pokazuje dwie klasy, A i B. B jest podklasą A; to znaczy, A jest klasą nadrzęd- ną (rodzicem) klasy B. Obie klasy posiadają metodę (QQ. Skorzystanie ze słowa 5JCFQYU w $(QQ oznacza, e $(QQ zakrywa #(QQ. Jeśli posiadasz dwie identyczne nazwy w dwóch klasach związanych ze sobą dziedzicznością, musisz skorzystać albo z mody- fikatora 5JCFQYU, albo z 1XGTTKFGU. (W rozdziale 10., „Dziedziczenie i polimorfizm”, znajdziesz szczegółowe informacje na temat u ywania 5JCFQYU i 1XGTTKFGU). /QF[HKMCVQT 5JCTGF Składowe 5JCTGF są dostępne bez potrzeby tworzenia egzemplarzy typów referencyj- nych lub bezpośrednich — odpowiednio klas lub struktur. W rozdziale 11., „Składowe współdzielone”, znajdziesz dokładne omówienie składowych współdzielonych. -QT[UVCPKG G URGE[HKMCVQTÎY FQUVúRW Klasy wspierają bardzo mądre powiedzenie divide et impera, dziel i rządź. Jako kon- struktor klasy, mo esz skupić się podczas definiowania wyłącznie na sposobie jej im- plementacji. Gdy korzystasz z klasy, stajesz się jej konsumentem. W tym momencie interesują Cię jedynie składowe publiczne, a w przypadku klas potomnych — składowe publiczne i chronione.
    • 266 Część II Zaawansowane programowanie zorientowane obiektowo Zaletą modyfikatorów dostępu jest to, e jako konsument nigdy nie musisz martwić się o składowe prywatne i zazwyczaj nie musisz równie myśleć o składowych chronio- nych. Jeśli będziesz pamiętał o ogólnej zasadzie mówiącej o definiowaniu nie więcej ni sześciu składowych publicznych w pojedynczej klasie, jako konsument takiej klasy będziesz zwolniony z cię aru większości detali implementacyjnych, które ukryte zosta- ną w składowych prywatnych i chronionych. Poprzez pewne zarządzanie kodem i sto- sowanie specyfikatorów dostępu ograniczających liczbę składowych, z jakimi muszą się uporać konsumenci, upraszczasz swój kod, przez co staje się on łatwiejszy do zarządza- nia i utrzymania. W metodach mo esz korzystać ze specyfikatorów dostępu 2WDNKE, 2TQVGEVGF, (TKGPF i 2TQVGEVGF (TKGPF. Na początku tego rozdziału, w podrozdziale „U ywanie specyfi- katorów dostępu do klas”, zostały omówione poszczególne specyfikatory. Poni sza lista bardzo krótko omawia ich wpływ na metody: Metody 2WDNKE mogą być wywołane wewnętrznie lub przez dowolnego konsumenta. Metody 2TQVGEVGF mogą być wywołane przez generalizatora (klasę potomną) lub wewnętrznie. Metody 2TKXCVG mogą być wywoływane wyłącznie wewnętrznie. Metody (TKGPF mogą być wywołane jedynie w obrębie tej samej aplikacji. Metody 2TQVGEVGF (TKGPF mogą być wywołane wewnętrznie lub przez potomka w obrębie tej samej aplikacji. W ksią ce znajdziesz setki przykładów wykorzystujących specyfikatory dostępu, a kil- kanaście w tym rozdziale. W pierwszym podrozdziale, „Definiowanie klas”, znajdziesz ogólne uwagi na temat liczby metod i stosowania specyfikatorów. &QFCYCPKG FCTG FQ MNCU Gdy chcesz poinformować konsumenta klasy, e coś się wewnątrz tej klasy wydarzyło, mo esz to przedstawić za pomocą zdarzenia: 2WDNKE 'XGPV 1P6GZV $[8CN 6GZV #U 5VTKPI 2TKXCVG 5WD &Q6GZV $[8CN 6GZV #U 5VTKPI 4CKUG'XGPV 1P6GZV 6GZV 'PF 5WD Klasa .QCFGT%NCUU (zobacz wydruk 7.6) wywołuje zdarzenie 1P6GZV dla ka dego wiersza odczytywanego z pliku tekstu. Zaletą korzystania ze zdarzeń jest to, e klasa nie musi wiedzieć, którzy konsumenci są zainteresowani otrzymywaniem informacji o zajściu zdarzenia. Kod .QCFGT%NCUU nie zmienia się w zale ności od tego, czy któryś z konsu- mentów obsługuje zdarzenie czy nie. Instrukcja 2WDNKE 'XGPV 1P6GZV $[8CN 6GZV #U 5VTKPI tworzy niejawnie typ &GNGICVG. Konsument, który chce obsłu yć zdarzenie 1P6GZV wygenerowane przez .QCFGT%NCUU,
    • Rozdział 7. Tworzenie klas 267 mo e do tego celu u yć instrukcji 9KVJ'XGPVU lub #FF*CPFNGT. Oto przykład u ycia dru- giej z nich: #FF*CPFNGT (.QCFGT1P6GZV #FFTGUU1H 1P6GZV Obiekt zawierający metodę 1P6GZV (w powy szej instrukcji) jest dodawany do listy wy- wołań &GNGICVG delegacji (.QCFGT1P6GZV. Zdarzenia nie są polimorficzne. Oznacza to, e nie mo esz jawnie przecią ać metod w klasach potomnych. Ogólną strategią stosowaną w takim przypadku jest opakowanie instrukcji 4CKUG'XGPVU w metodę i u ycie tej metody (zobacz &Q6GZV) jako proxy w celu wywołania zdarzenia. Poprzez skorzystanie z proxy przy wywoływaniu zdarzeń, mo- emy przesłonić go w klasach potomnych, gdy tylko chcemy zmienić zachowanie się zdarzenia w momencie jego wywołania. Obsługa zdarzeń zmieniła się znacząco w Visual Basic .NET, włączając w to wprowa- dzenie klas &GNGICVG i /WNVKECUV&GNGICVG, które bardzo usprawniły tę obsługę. Roz- dział 8., „Dodawanie zdarzeń” oraz 9., „Delgacje” szczegółowo omawia tematy obsługi zdarzeń i delegacji. &GHKPKQYCPKG MNCU CIPKG F QP[EJ Klasa zagnie d ona jest po prostu klasą zdefiniowaną w klasie. Klasy zagnie d one mogą być definiowane ze wszystkich elementów dowolnej innej klasy. Oto szkielet kodu dla klasy zagnie d onej: 2WDNKE %NCUU 1WVGT 2WDNKE %NCUU 0GUVGF 'PF %NCUU 'PF %NCUU Celem tworzenia klas zagnie d onych jest zgromadzenie grupy elementów posiadają- cych wspólne cechy w obrębie zawierającej je klasy. Na przykład, jeśli masz klasę i ja- kieś pola, właściwości i metody definiujące pewną koncepcję, jednak są one osobno, mo esz zaimplementować klasę zagnie d oną, w której zgromadzisz te elementy. Generalnie, nie będziesz często wykorzystywał klas zagnie d onych. Jakakolwiek im- plementacja, która mo e być zrobiona z u yciem klas zagnie d onych, mo e być z po- wodzeniem zrobiona bez nich. Jeśli temat ten Cię bardziej interesuje, mo esz poczytać na temat bardziej zaawansowanych tworów, np. o idiomie list-koperta, w ksią ce Jamesa Copliena „Advanced C++”. Wydruk 7.7 przedstawia przykład klas zagnie d onych, prezentując sposoby ich implementacji i gramatykę języka. 9[FTWM  Klasy zagnieżdżone, dziedziczenie i wielowątkowość w programie demonstracyjnym TrafficLight.sln  2WDNKE %NCUU 5KIPCN  4GIKQP 5M CFQYG RWDNKEPG  2WDNKE 'XGPV 1P%JCPIG $[8CN UGPFGT #U 5[UVGO1DLGEV A  $[8CN G #U 5[UVGO'XGPV#TIU
    • 268 Część II Zaawansowane programowanie zorientowane obiektowo   2WDNKE 5WD &TCY $[8CN )TCRJKE #U )TCRJKEU  )TCRJKE(KNN4GEVCPING $TWUJGU$TQYP 4GEV  &TCY.KIJVU )TCRJKE  'PF 5WD   2WDNKE 5WD 0GY $[8CN 4GEV #U 4GEVCPING  (4GEV  4GEV  2QUKVKQP.KIJVU  6WTP1P)TGGP  %TGCVG6JTGCF  'PF 5WD   2WDNKE 5WD &KURQUG  5VCVKE &QPG #U $QQNGCP  (CNUG  +H &QPG 6JGP 'ZKV 5WD  &QPG  6TWG  -KNN6JTGCF  )%5WRRTGUU(KPCNKG /G  'PF 5WD   2WDNKE 5WD 0GZV5KIPCN  9JKNG (6JTGCF+U#NKXG  (6JTGCF5NGGR 5NGGR6KOG  %JCPIG5VCVG  &Q%JCPIG  'PF 9JKNG  'PF 5WD   'PF 4GIKQP   4GIKQP 5M CFQYG EJTQPKQPG   &GUVTWMVQT  2TQVGEVGF 1XGTTKFGU 5WD (KPCNKG  &KURQUG  'PF 5WD   2TQVGEVGF 5WD %TGCVG6JTGCF  (6JTGCF  0GY 6JTGCFKPI6JTGCF #FFTGUU1H 0GZV5KIPCN  (6JTGCF+U$CEMITQWPF  6TWG  5VCTV5KIPCN  'PF 5WD   2TQVGEVGF 5WD 5VCTV5KIPCN  (6JTGCF5VCTV  'PF 5WD   2TQVGEVGF 5WD 5VQR5KIPCN  (6JTGCF#DQTV  (6JTGCF,QKP  'PF 5WD   2TQVGEVGF 5WD -KNN6JTGCF  5VQR5KIPCN  (6JTGCF  0QVJKPI  'PF 5WD
    • Rozdział 7. Tworzenie klas 269   2TQVGEVGF 5WD &TCY.KIJVU $[8CN )TCRJKE #U )TCRJKEU  &KO + #U +PVGIGT  (QT +   6Q (.KIJVU)GV7RRGT$QWPF   (.KIJVU + &TCY )TCRJKE  0GZV  'PF 5WD   'PF 4GIKQP   4GIKQP 5M CFQYG RT[YCVPG  2TKXCVG (.KIJVU #U .KIJV  A  ]0GY )TGGP.KIJV  0GY ;GNNQY.KIJV  0GY 4GF.KIJV _  2TKXCVG (4GEV #U 4GEVCPING  2TKXCVG (6JTGCF #U 6JTGCFKPI6JTGCF   2TKXCVG 4GCF1PN[ 2TQRGTV[ )TGGP #U .KIJV  )GV  4GVWTP (.KIJVU   'PF )GV  'PF 2TQRGTV[   2TKXCVG 4GCF1PN[ 2TQRGTV[ ;GNNQY #U .KIJV  )GV  4GVWTP (.KIJVU   'PF )GV  'PF 2TQRGTV[   2TKXCVG 4GCF1PN[ 2TQRGTV[ 4GF #U .KIJV  )GV  4GVWTP (.KIJVU   'PF )GV  'PF 2TQRGTV[   2TKXCVG 4GCF1PN[ 2TQRGTV[ 4GEV #U 4GEVCPING  )GV  4GVWTP (4GEV  'PF )GV  'PF 2TQRGTV[   2TKXCVG 5WD 2QUKVKQP.KIJVU   &KO + #U +PVGIGT  (QT +   6Q (.KIJVU)GV7RRGT$QWPF   (.KIJVU + 4GEV  )GV4GEV +  0GZV   'PF 5WD   2TKXCVG 5WD 6WTP1P)TGGP  )TGGP5VCVG  6TWG  'PF 5WD   2TKXCVG 5WD &Q%JCPIG  4CKUG'XGPV 1P%JCPIG /G 0QVJKPI  'PF 5WD 
    • 270 Część II Zaawansowane programowanie zorientowane obiektowo   2TKXCVG (WPEVKQP )GV4GEV $[8CN +PFGZ #U +PVGIGT #U 4GEVCPING  4GVWTP 0GY 4GEVCPING 4GEV.GHV  A  4GEV6QR  %+PV /CVJ4QWPF   +PFGZ  
    • 4GEV*GKIJV  A  4GEV9KFVJ   %+PV /CVJ4QWPF 4GEV*GKIJV      'PF (WPEVKQP   2TKXCVG 5WD %JCPIG5VCVG  5VCVKE %WTTGPV #U +PVGIGT    %WTTGPV  %WTTGPV  /QF   &KO + #U +PVGIGT   (QT +  (.KIJVU)GV.QYGT$QWPF  6Q A  (.KIJVU)GV7RRGT$QWPF   (.KIJVU + 5VCVG  +  %WTTGPV  0GZV  'PF 5WD   2TKXCVG (WPEVKQP 5NGGR6KOG #U +PVGIGT  5VCVKE 6 #U +PVGIGT  ] _  +H ;GNNQY5VCVG 6JGP  4GVWTP 6   'NUG  4GVWTP 6   'PF +H  'PF (WPEVKQP   'PF 4GIKQP    4GIKQP 5M CFQYG CIPKG F QPG   8KTVWCN #DUVTCEV 0GUVGF .KIJV %NCUU  $CUG ENCUU HQT VJG NKIJV UKIPCN NKIJV ENCUUGU   2TKXCVG /WUV+PJGTKV %NCUU .KIJV  2WDNKE 5VCVG #U $QQNGCP  (CNUG  2WDNKE 4GEV #U 4GEVCPING   2TQVGEVGF /WUV1XGTTKFG 4GCF1PN[ 2TQRGTV[ A  $TWUJ#TTC[ #U $TWUJ   2TQVGEVGF (WPEVKQP )GV$TWUJ #U $TWUJ  +H 5VCVG 6JGP  4GVWTP $TWUJ#TTC[   'NUG  4GVWTP $TWUJ#TTC[   'PF +H  'PF (WPEVKQP   2WDNKE 5WD &TCY $[8CN )TCRJKE #U )TCRJKEU  )TCRJKE(KNN'NNKRUG )GV$TWUJ  4GEV  'PF 5WD   2TQVGEVGF 1XGTTKFGU 5WD (KPCNKG  4GEV  0QVJKPI  'PF 5WD  'PF %NCUU
    • Rozdział 7. Tworzenie klas 271   <CIPKG F QPC MNCUC 4GF.KIJV FKGFKE[ .KIJV  2TKXCVG %NCUU 4GF.KIJV  +PJGTKVU .KIJV   2TQVGEVGF 1XGTTKFGU 4GCF1PN[ 2TQRGTV[ $TWUJ#TTC[ #U $TWUJ  )GV  5VCVKE $TWUJ #U $TWUJ  ]$TWUJGU)TC[ A  $TWUJGU4GF_  4GVWTP $TWUJ  'PF )GV  'PF 2TQRGTV[  'PF %NCUU   <CIPKG F QPC MNCUC ;GNNQY.KIJV FKGFKE[ .KIJV  2TKXCVG %NCUU ;GNNQY.KIJV  +PJGTKVU .KIJV   2TQVGEVGF 1XGTTKFGU 4GCF1PN[ 2TQRGTV[ $TWUJ#TTC[ #U $TWUJ  )GV  5VCVKE $TWUJ #U $TWUJ  ]$TWUJGU)TC[ A  $TWUJGU;GNNQY_  4GVWTP $TWUJ  'PF )GV  'PF 2TQRGTV[   'PF %NCUU   <CIPKG F QPC MNCUC )TGGP.KIJV FKGFKE[ .KIJV  2TKXCVG %NCUU )TGGP.KIJV  +PJGTKVU .KIJV  2TQVGEVGF 1XGTTKFGU 4GCF1PN[ 2TQRGTV[ $TWUJ#TTC[ #U $TWUJ  )GV  5VCVKE $TWUJ #U $TWUJ  ]$TWUJGU)TC[ A  $TWUJGU)TGGP_  4GVWTP $TWUJ  'PF )GV  'PF 2TQRGTV[  'PF %NCUU  'PF 4GIKQP   'PF %NCUU Ze względu na to, e wydruk ten jest bardzo długi, jego szczegółowe omówienie zostało podzielone na poszczególne sekcje. Ka da z nich prezentuje pewien określony aspekt kodu. <TQWOKGPKG EGNW MQT[UVCPKC MNCU CIPKG F QP[EJ Motywacja do u ywania klas zagnie d onych wydaje się być dosyć niejasna, zwłaszcza e ka da zagnie d ona klasa mo e być technicznie zaimplementowana jako zwykła kla- sa. Istnieją pewne ściśle określone powody do wprowadzania klas zagnie d onych, jed- nak jest ich zaledwie kilka i będziesz się z nimi bardzo rzadko spotykał.
    • 272 Część II Zaawansowane programowanie zorientowane obiektowo Aby zademonstrować techniczne aspekty wprowadzania klas zagnie d onych, napisa- łem przykładowy program TrafficSignal.sln. Światła sygnalizacji świetlnej — czerwone na górze, ółte w środku i zielone na dole — idealnie nadają się na elementy klasy za- gnie d onej. Jest raczej mało prawdopodobne, e spotkasz na ulicy pojedynczy sygnał świetlny — tylko w jednym kolorze — którego stan będzie zale eć on innych świateł nie towarzyszących jemu. (Mo e istnieć pojedyncze ółte światło pulsujące, jednak w tym przypadku mo na je zaimplementować jako element osobnego sygnału świetlnego. Przy- kład ten ilustruje wątpliwości, jakie często mo na napotkać przy korzystaniu z klas za- gnie d onych: za ka dym razem, kiedy korzystasz z tego typu klasy, znajdzie się wy- jątek, który sugeruje zrezygnowanie z zagnie d ania). 5KIPCN zawiera trzy egzemplarze klasy .KIJV. Stanowią one sens jedynie jako całość (tak zakładamy w naszym przykładzie), potrzebujemy więc więcej ni jedno światło. Wpro- wadzimy je zatem jako klasę zagnie d oną i utworzymy trzy egzemplarze tej klasy. &GHKPKQYCPKG MNCU[ 5KIPCN Klasa 5KIPCN reprezentuje trzystanowe, czerowno- ółto-zielone światło sygnalizacji dro- gowej. 5KIPCN będzie zdefiniowany tak, aby rysował na ekranie wyjściowym swój sym- bol za pomocą obiektu )TCRJKEU oraz będzie reprezentować poszczególne stany za po- mocą odpowiednich kolorów. Klasa 5KIPCN posiada tablicę trzech obiektów .KIJV, których stany są ze sobą odpowied- nio powiązane i będą się zmieniać tak, jak zmieniają się światła w rzeczywistości. Dwa sygnały z ró nymi stanami są pokazane na rysunku 7.4. 4[UWPGM  Dwa egzemplarze klasy Signal z rozwiązania TrafficSignal.sln Wszystkie składowe klasy 5KIPCN są zdefiniowane w wierszach 1. – 146. wydruku 7.7. W poni szych podrozdziałach omawiam poszczególne aspekty tej klasy. -QT[UVCPKG HWPMELK UMTCECPKC MQFW Y EGNW NGRUGL QTICPKCELK Pierwszą rzeczą, jaką zauwa ysz na wydruku 7.7, jest to, e wykorzystana została funk- cja skracania kodu za pomocą dyrektywy 4GIKQP. Długim, skomplikowanym wydrukom
    • Rozdział 7. Tworzenie klas 273 klas typu 5KIPCN na pewno przyda się trochę uporządkowania. Górna połowa wydruku zawiera składowe klasy 5KIPCN, a dolna — począwszy od wiersza 149. — definiuje kla- sy zagnie d one. Przez dodanie dyrektywy 4GIKQP mo esz zwijać i rozwijać fragmenty kodu, ułatwiając sobie tym samym pracę z programem. Warto równie deklarować egzemplarze w kolejności ich wa ności. Konsumentów inte- resują tylko składowe 2WDNKE, więc je umieść jako pierwsze w kodzie. Generalizatorów dotyczą równie składowe 2TQVGEVGF, więc one niech będą po publicznych. Na końcu umieść składowe 2TKXCVG, które dostępne są jedynie twórcy klasy. Takie uporządkowanie na pewno się przydaje, jednak w przypadku stosunkowo prostych i krótkich klas składowe mogą być umieszczane w kolejności ich tworzenia, bez zachowywania jakiejś szczególnej kolejności. Jako ostatnie i najmniej znaczące w wydruku definiujemy klasy zagnie d one. Gdyby były one istotne dla konsumentów, nie byłyby klasami zagnie d onymi. &GHKPKQYCPKG MQPUVTWMVQTC K FGUVTWMVQTC Klasa 5KIPCN posiada trzy egzemplarze klasy .KIJV i obiekt 6JTGCF. Z tego powodu kon- struktor, destruktor oraz metody &KURQUG zostały dodane do klasy 5KIPCN. Konstruktor i &KURQUG zostały zdefiniowane odpowiednio w wierszach 11. – 16. i 18. – 24. Dla pew- ności, fragment ten został przedstawiony na wydruku 7.8. Metoda 2TQVGEVGF (KPCNKG słu y do wywoływania metody &KURQUG — wiersze 39. – 41. — i nie została poni ej przedstawiona. 9[FTWM  Konstruktor oraz metoda Dispose klasy Signal  2WDNKE 5WD 0GY $[8CN 4GEV #U 4GEVCPING  (4GEV  4GEV  2QUKVKQP.KIJVU  6WTP1P)TGGP  %TGCVG6JTGCF  'PF 5WD   2WDNKE 5WD &KURQUG  5VCVKE &QPG #U $QQNGCP  (CNUG  +H &QPG 6JGP 'ZKV 5WD  &QPG  6TWG  -KNN6JTGCF  )%5WRRTGUU(KPCNKG /G  'PF 5WD Konstruktor 5WD 0GY deleguje wszystkie swoje zadania do dobrze znanych metod, któ- rych nazwy bezpośrednio „mówią”, co jest w danej chwili robione. Inną strategią jest dodanie metody +PKVKCNKG i wydelegowanie do niej całości kodu inicjującego; techni- ka ta umo liwi ponowne zainicjowanie obiektu bez konieczności tworzenia nowego obiektu. W konstruktorze tym: określono, e ograniczający prostokąt jest przechowy- wany w polu, ustawiono światła .KIJVU na określonej pozycji, włączono światło zielone oraz utworzony został wątek 6JTGCF.
    • 274 Część II Zaawansowane programowanie zorientowane obiektowo Metoda &KURQUG wykorzystuje zmienną lokalną w roli wartownika. Dzięki niemu drugie i kolejne wywołanie &KURQUG nie wykonuje adnych czynności. Za pierwszym razem natomiast metoda usuwa wszystkie wątki, które kontrolują stan świateł i powstrzymuje systemowy odzyskiwacz pamięci. Same światła nie są zwalniane, gdy zostały utwo- rzone na zewnątrz konstruktora w wierszach 73. i 74. poprzez element inicjujący tablicę. 6YQTGPKG YæVMC YKCVG W wierszu 15. (zobacz wydruk 7.7 i 7.8) wywoływana jest metoda %TGCVG6JTGCF. Wszystkie metody zarządzające wątkami zostały pokazane na wydruku 7.9, będącym fragmentem kodu z wydruku 7.7. 9[FTWM  Metody obsługujące wątki w klasie Signal  2TQVGEVGF 5WD %TGCVG6JTGCF  (6JTGCF  0GY 6JTGCFKPI6JTGCF #FFTGUU1H 0GZV5KIPCN  (6JTGCF+U$CEMITQWPF  6TWG  5VCTV5KIPCN  'PF 5WD   2TQVGEVGF 5WD 5VCTV5KIPCN  (6JTGCF5VCTV  'PF 5WD   2TQVGEVGF 5WD 5VQR5KIPCN  (6JTGCF#DQTV  (6JTGCF,QKP  'PF 5WD   2TQVGEVGF 5WD -KNN6JTGCF  5VQR5KIPCN  (6JTGCF  0QVJKPI  'PF 5WD W wierszu 44. tworzony jest egzemplarz klasy 5[UVGO6JTGCFKPI6JTGCF. Konstruktor klasy 6JTGCF pobiera adres procedury #FFTGUU1H; procedura ta jest w miejscu, gdzie wątek się rozwidli podczas swojego startu. Wiersz 45. oznacza, e wątek staje się wąt- kiem w tle, umo liwiając aplikacji wyjście i zatrzymanie wątków sygnału. W wierszu 46. wywoływana jest metoda 5VCTV5KIPCN, która załącza sygnał świetlny poprzez uru- chomienie procedury z wiersza 49. Wraz z wywołaniem metody &KURQUG wywoływana jest -KNN6JTGCF. Z wydruku mo na wywnioskować, e -KNN6JTGCF uruchamia 5VQR5K IPCN i zwalnia obiekt wątka poprzez przypisanie go do 0QVJKPI. 5VQR5KIPCN wywołuje metodę (6JTGCF#DQTV, a (6JTGCF,QKP czeka na zakończenie działania wątku. (6JTG CF#DQTV unicestwia wątek poprzez wywołanie wyjątku 6JTGCF#DQTV'ZEGRVKQP, którego nie da się przechwycić; wyjątek ten umo liwia wykonanie wszystkich bloków (KPCNN[, potrzebne jest więc wywołanie ,QKP, aby upewnić się, e wątek został zakończony. Wielowątkowość jest całkowicie nowym zagadnieniem w Visual Basic .NET. Jeśli wcze- śniej nie programowałeś w języku umo liwiającym obsługę wielu wątków, mo e to być dla Ciebie nie lada wyzwaniem. Klasa 6JTGCF i programowanie wielowątkowe w Visual Basic .NET zostały dokładnie omówione w rozdziale 14, „Aplikacje wielowątkowe”.
    • Rozdział 7. Tworzenie klas 275 4[UQYCPKG U[IPCNKCVQTC Y[MQT[UVCPKGO FCTGPKC Obiekty 5KIPCN są rysowane dla ka dej kontrolki, która przeka e swój obiekt )TCRJKEU metodzie 5KIPCN&TCY. (W rzeczywistości sygnał powinien być kontrolką, ale odeszli- byśmy znacząco od tematu klas zagnie d onych, dyskutując teraz o tym). Przyjrzyj się poni szym fragmentom kody z wydruku 7.7:  2WDNKE 5WD &TCY $[8CN )TCRJKE #U )TCRJKEU  )TCRJKE(KNN4GEVCPING $TWUJGU$TQYP 4GEV  &TCY.KIJVU )TCRJKE  'PF 5WD   2TQVGEVGF 5WD &TCY.KIJVU $[8CN )TCRJKE #U )TCRJKEU  &KO + #U +PVGIGT  (QT +   6Q (.KIJVU)GV7RRGT$QWPF   (.KIJVU + &TCY )TCRJKE  0GZV  'PF 5WD   2TQVGEVGF (WPEVKQP )GV$TWUJ #U $TWUJ  +H 5VCVG 6JGP  4GVWTP $TWUJ#TTC[   'NUG  4GVWTP $TWUJ#TTC[   'PF +H  'PF (WPEVKQP   2WDNKE 5WD &TCY $[8CN )TCRJKE #U )TCRJKEU  )TCRJKE(KNN'NNKRUG )GV$TWUJ  4GEV  'PF 5WD W tych trzech metodach zrealizowane jest rysowanie obiektów. W wierszach 6. – 9. 5K IPCN&TCY rysuje 5KIPCN jako 4GEVCPING (prostokąt) i wywołuje 5KIPCN&TCY.KIJVU w celu dodania do prostokąta świateł. &TCY.KIJVU wykorzystuje pętlę do narysowania ka dego ze świateł, przy okazji prezentując dywersyfikację zadań oferowanych przez klasy i klasy zagnie d one. .KIJV&TCY wywołuje )TCRJKEU(KNN'NNKRUG (u ywając argumentu )TC RJKE), u ywając 4GEV jako obszaru ograniczającego dane światło oraz .KIJV)GV$TWUJ do określenia rodzaju pędzla na podstawie aktualnego stanu światła. Gdy wywoływana jest metoda rysująca, zajmuje się ona wyłącznie obiektami 'NNKRUGU, $TWUJGU i 4GEV, a nie zmianą poszczególnych stanów czy obliczaniem granic obszarów. Wiersze 163. i 165. wykorzystują polimorficzną właściwość $TWUJ#TTC[ w celu uzyska- nia poprawnej tablicy obiektów pędzla na podstawie egzemplarza lampy. Jeśli 5VCVG  (CNUG, zwracany jest pędzel wyłączony; w przeciwnym wypadku właściwość zwróci pędzel o określonym przez egzemplarz lampy kolorze. Rozdział 10., „Dziedziczenie i polimorfizm”, zawiera bardziej obszerną dyskusję na temat dziedziczenia i zagadnień związanych z polimorfizmem; przedstawia równie sposoby definiowania i implementacji interfejsów.
    • 276 Część II Zaawansowane programowanie zorientowane obiektowo &GHKPKQYCPKG CDUVTCME[LPGL MNCU[ DCQYGL .KIJV .KIJV, )TGGP.KIJV, ;GNNQY.KIJV oraz 4GF.KIJV są klasami zagnie d onymi. .KIJV wyko- rzystuje modyfikator /WUV+PJGTKV. Klasa .KIJV jest przykładem abstrakcyjnych klas ba- zowych w Visual Basic .NET, co oznacza, e ma ona być raczej potomkiem i nie ma być utworzona bezpośrednio. Musi korzystać z modyfikatora /WUV+PJGTKV, poniewa dekla- ruje abstrakcyjną właściwość: 2TQVGEVGF /WUV1XGTTKFG 4GCF1PN[ 2TQRGTV[ $TWUJ#TTC[ #U $TWUJ Zauwa , e $TWUJ#TTC[ w wierszach 158. i 159. na wydruku 7.7 nie posiada bloku procedu- ry; jest to wyłącznie deklaracja. Instrukcje z /WUV1XGTTKFG odnoszą się do wirtualnych i abs- trakcyjnych składowych, co oznacza, e muszą być implementowane w klasie potomnej. Wirtualne, abstrakcyjne składowe są analogią do deklaracji interfejsu w klasach COM. )TGGP.KIJV, ;GNNQY.KIJV i 4GF.KIJV — ka da z nich musi implementować właściwość $TWUJ#TTC[, w przeciwnym razie będą wirtualne i abstrakcyjne. Instrukcje deklarujące są wykorzystywane w celu pomocy przy wprowadzaniu klas po- tomnych. Metoda &TCY klasy .KIJV zale y od )GV$TWUJ, a )GV$TWUJ w rezultacie zale y od tego, czy uda się uzyskać odpowiedni pędzel i kolor na podstawie stanu określonej lampy. W językach strukturalnych (lub niepoprawnie w językach obiektowych) ten ro- dzaj zachowania był implementowany z wykorzystaniem instrukcji ECUG. +ORNGOGPVQYCPKG YKCVG U[IPCNKCELK Klasy świateł sygnalizacji same w sobie są łatwe do implementacji. Ka de poszczegól- ne światło wymaga jedynie dziedziczenia z .KIJV oraz zaimplementowania właściwości tylko do odczytu $TWUJ#TTC[. Wydruk 7.10 przedstawia jedną z tych klas — 4GF.KIJV. (Treść wszystkich świateł ró ni się jedynie wartościami wykorzystywanymi do zaini- cjowania $TWUJ#TTC[). 9[FTWM  Sposób implementacji jednego ze świateł  <CIPKG F QPC MNCUC 4GF.KIJV FKGFKE[ .KIJV  2TKXCVG %NCUU 4GF.KIJV  +PJGTKVU .KIJV   2TQVGEVGF 1XGTTKFGU 4GCF1PN[ 2TQRGTV[ $TWUJ#TTC[ #U $TWUJ  )GV  5VCVKE $TWUJ #U $TWUJ  ]$TWUJGU)TC[ A  $TWUJGU4GF_  4GVWTP $TWUJ  'PF )GV  'PF 2TQRGTV[  'PF %NCUU W wierszu 182. wprowadzona jest chroniona, przesłonięta i tylko do odczytu właściwość o nazwie $TWUJ#TTC[. Statyczna tablica pędzli jest inicjowana pędzlami globalnymi zde- finiowanymi w obiekcie $TWUJGU. Klasa 4GF.KIJV wykorzystuje pędzle koloru szarego i czerwonego.
    • Rozdział 7. Tworzenie klas 277 Istnieje kilka sposobów, na jakie moglibyśmy zaimplementować kolorowe lampy sy- gnalizacji świetlnej. Moglibyśmy na przykład u yć jednej klasy .KIJV i metod fabrycz- nych, które inicjują wartości pędzla na podstawie rodzaju światła; rodzaj ten mógłby być zdefiniowany z wykorzystaniem typu wyliczeniowego. W programowaniu, jak we wszystkich dziedzinach ycia, musimy przyjąć pewien sposób postępowania. W tym rozdziale wybrałem podejście, które najlepiej obrazuje klasy zagnie d one. W rezulta- cie otrzymaliśmy ogólnie bardzo dobry kod. 2QFUWOQYCPKG RTQITCOW 6TCHHKE.KIJV W systemie produkcyjnym przykładowy program obsługi świateł sygnalizacyjnych nada- wałby się lepiej jako aplikacja ni komponent. Jeśli modelowałbyś światła miejskie, na pewno chciałbyś jeszcze raz przemyśleć wszystkie wątki. W mieście wielkości Gliwic miałbyś 40 wątków, ale w Warszawie komputer eksplodowałby, przełączając wszystkie niezbędne do prawidłowego funkcjonowania miasta wątki. W dodatku światła sygnali- zacyjne wymagają koordynacji. Lepszą implementacją byłby na przykład mened er wątków, który koordynowałby światła na poszczególnych skrzy owaniach oraz przy- dzielałby czasy trwania poszczególnym sygnałom. W przypadku symulacji wizualnych aspektów zarządzania ruchem samochodowym na- le ałoby równie dopracować grafikę naszej aplikacji i dołączyć inne rzeczy związane z tym zagadnieniem. 6YQTGPKG GIGORNCT[ MNCU Do tej pory spotkałeś się ju z wieloma przykładami tworzenia egzemplarzy klas. Jed- nak e ten rozdział jest pierwszym, w którym temat klas omawiany jest oddzielnie. Przyjrzyjmy się więc jeszcze raz składni tworzenia obiektów. Klasy są określane mianem typów referencyjnych. Typy takie, w przeciwieństwie do typów bezpośrednich, są tworzone poprzez deklarację zmiennej i u ycie słowa 0GY, a po nim nazwy klasy i nawiasów: &KO TGHGTGPEG #U 0GY %NCUU Przykład ten wygląda, jak gdybyśmy wywoływali procedurę o nazwie %NCUU. Jest to jednak forma słu ąca do konstrukcji obiektu. W rzeczywistości kod taki wywołuje kon- struktora 5WD 0GY zdefiniowanego w klasie %NCUU. Jeśli masz parametry, które chcesz przekazać do konstruktora, umieszczasz je w nawiasach przy nazwie klasy, cały czas jest to jednak wywoływanie 5WD 0GY, tym razem tylko przecią onej. Składnia taka mo e wprowadzać małe zamieszanie. Oto przykład tworzenia egzemplarza klasy 5KIPCN z po- przedniego podrozdziału: &KO #5KIPCN #U 0GY 5KIPCN 0GY 4GEVCPING     Jeśli procedura pobiera obiekt, rozważ możliwość utworzenia obiektu — tak jak 0GY 4GEVCPING     — podczas wywołania procedury. Technika ta pomoże w usuwaniu niepotrzebnych zmiennych tymczasowych.
    • 278 Część II Zaawansowane programowanie zorientowane obiektowo Powy sza instrukcja deklaruje i inicjuje egzemplarz klasy 5KIPCN. Wywołuje ona kon- struktora 5KIPCN0GY , przekazując egzemplarz nowego prostokąta (zobacz wiersz 11. na wydruku 7.7.). Taki sposób wywoływania jest dość dziwny, jednak decyzje w tej spra- wie podejmował Microsoft podczas projektowania Visual Basic .NET. W innych językach mo na spotkać inne formy konstruktorów i destruktorów. C++ u ywa operatora PGY, który mo e być przecią ony, przy czym konstruktor ma on taką samą na- zwę jak klasa, a nazwa destruktora jest równie nazwą klasy, lecz poprzedzoną znakiem tyldy (`). Object Pascal korzysta z metod %TGCVG i &GUVTQ[, ale w rzeczywistości kon- struktory i destruktory oznacza słowami kluczowymi EQPUVTWEVQT i FGUVTWEVQT. 2QFUWOQYCPKG Konstrukcja klasy ró ni się między VB6 a Visual Basic .NET. W VB6 klasy są interfej- sami i literalnie u ywają słowa KPVGTHCEG. Klasy Visual Basic .NET wykorzystują słów- ko %NCUU i umo liwiają dziedziczenie, cechę wcześniej niespotykaną. Ten rozdział jako pierwszy z rozdziałów tej ksią ki podejmuje się przedstawienia bardziej zaawansowa- nych zagadnień. Przedstawiono tu podstawowe sposoby definiowania klas, dodawania pól, właściwo- ści, zdarzeń i metod; pokazano, jak radzić sobie ze zło onością specyfikatorów dostę- pu i jak stosować modyfikatory. W tym rozdziale zostały pokazane zmiany wprowa- dzone w Visual Basic .NET do interfejsów, jak równie sposoby implementacji metod interfejsu i klas zagnie d onych. Dowiedziałeś się, jak korzystać z wielowątkowości i dziedziczenia. Rozdziały 8., „Dodawanie zdarzeń”, i 9., „Delegacje”, rozszerzają przedstawione w tym rozdziale zagadnienia zdarzeń i delegacji, a rozdział 10., „Dziedziczenie i polimorfizm”, szczegółowo prezentuje dziedziczenie i polimorfizm. W rozdziale 12., „Definiowanie atrybutów”, dowiesz się, jak wydajnie wykorzystywać atrybuty.