SlideShare a Scribd company logo
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[UVGOKCIPQUVKEUGDWIIGT*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[UVGOKCIPQUVKEU, 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 1DLGEVKURQUGF'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 +KURQUCDNGKURQUG
   5VCVKE (KURQUGF #U $QQNGCP  (CNUG
   +H 
(KURQUGF 6JGP 'ZKV 5WD
   (KURQUGF  6TWG
   %NQUG

   (#TTC[.KUV  0QVJKPI
   )%5WRRTGUU(KPCNKG
/G
 'PF 5WD

Metoda KURQUG implementuje +KURQUCDNGKURQUG (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

                  #RRNKECVKQPQ'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 +KURQUCDNGKURQUG
            +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, 2TKPVCVG. 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 /WNVKECUVGNGICVG, 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 5KIPCNTCY. (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
      IPCNTCY rysuje 5KIPCN jako 4GEVCPING (prostokąt) i wywołuje 5KIPCNTCY.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. .KIJVTCY 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.

More Related Content

PDF
Visual Basic .NET. Encyklopedia
PDF
Programowanie obiektowe w Visual Basic .NET dla każdego
PDF
Visual Basic 2005. Wprowadzenie do programowania w .NET
PDF
Visual Basic 2005. Zapiski programisty
PDF
Visual Basic 2005. Programowanie
PDF
Visual Basic 2005. Od podstaw
PDF
Visual C++ 2005 Express Edition. Tworzenie aplikacji dla Windows
PDF
Macromedia Flash 8. Oficjalny podręcznik
Visual Basic .NET. Encyklopedia
Programowanie obiektowe w Visual Basic .NET dla każdego
Visual Basic 2005. Wprowadzenie do programowania w .NET
Visual Basic 2005. Zapiski programisty
Visual Basic 2005. Programowanie
Visual Basic 2005. Od podstaw
Visual C++ 2005 Express Edition. Tworzenie aplikacji dla Windows
Macromedia Flash 8. Oficjalny podręcznik

What's hot (20)

PDF
Visual C# 2005. Zapiski programisty
PDF
ABC Delphi 2006
PDF
Aplikacje w Visual C++ 2005. Przykłady
PDF
J2EE. Vademecum profesjonalisty. Wydanie II
PDF
J2EE. Stosowanie wzorców projektowych
PDF
Wstęp do programowania w języku C#
PDF
Visual C# .NET. Encyklopedia
PDF
C++Builder i Turbo C++. Podstawy
PDF
Adobe Premiere 6.5. Podręcznik montażysty
PDF
Macromedia Studio 8. Oficjalny podręcznik
PDF
ActionScript 2.0. Od podstaw
PDF
100 sposobów na Visual Studio
PDF
Visual Basic .NET. Wzorce projektowe
PDF
Macromedia Flash MX 2004. Sztuka projektowania
PDF
PHP5. Zaawansowane programowanie
PDF
Język C++. Gotowe rozwiązania dla programistów
PDF
J2EE. Podstawy programowania aplikacji korporacyjnych
PDF
J2EE. Wzorce projektowe. Wydanie 2
PDF
ASP.NET 2.0. Projektowanie aplikacji internetowych
PDF
Praktyczny kurs Java
Visual C# 2005. Zapiski programisty
ABC Delphi 2006
Aplikacje w Visual C++ 2005. Przykłady
J2EE. Vademecum profesjonalisty. Wydanie II
J2EE. Stosowanie wzorców projektowych
Wstęp do programowania w języku C#
Visual C# .NET. Encyklopedia
C++Builder i Turbo C++. Podstawy
Adobe Premiere 6.5. Podręcznik montażysty
Macromedia Studio 8. Oficjalny podręcznik
ActionScript 2.0. Od podstaw
100 sposobów na Visual Studio
Visual Basic .NET. Wzorce projektowe
Macromedia Flash MX 2004. Sztuka projektowania
PHP5. Zaawansowane programowanie
Język C++. Gotowe rozwiązania dla programistów
J2EE. Podstawy programowania aplikacji korporacyjnych
J2EE. Wzorce projektowe. Wydanie 2
ASP.NET 2.0. Projektowanie aplikacji internetowych
Praktyczny kurs Java
Ad

Viewers also liked (20)

PDF
Blokada wykonywania wielu akcji z jednego widoku
DOC
CHIPUL MESIANIC AL LUI YEŞUA NOŢRI (IISUS NAZARINEANUL)
PDF
Raport analityczny NCIndex30
PPTX
Metody Deep Learning - Wykład 2
DOC
дії населення в разі виявлення запаху газу
PDF
Temperatura biwalencyjna dla powietrznej pompy ciepła
PDF
2006.07 Raport Strategiczny IAB 2005
PDF
Materiały oraz ich właściwości stosowane do budowy instalacji wodociągowych i...
PDF
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBA
PPT
88 uklad okresowy_pierwiastkow
PDF
iqt_n_ptn_17_06_14 (4)
DOC
Fałszerstwa ewolucji. polish
PPTX
2100. 3 класс. Урок 1.5 Арифметические действия над числами
PDF
Rewitalizacja vs recykling (Krzysztof Kalitko)
PDF
Mitsubishi Electric Księga Automatyzacji2014
PDF
Produkowanie koncentratów spożywczych
PDF
Koszty podgrzewania ciepłej wody użytkowej CWU
PDF
Restart raport końcowy
 
PDF
Sygnity S.A. WULKAN
Blokada wykonywania wielu akcji z jednego widoku
CHIPUL MESIANIC AL LUI YEŞUA NOŢRI (IISUS NAZARINEANUL)
Raport analityczny NCIndex30
Metody Deep Learning - Wykład 2
дії населення в разі виявлення запаху газу
Temperatura biwalencyjna dla powietrznej pompy ciepła
2006.07 Raport Strategiczny IAB 2005
Materiały oraz ich właściwości stosowane do budowy instalacji wodociągowych i...
MS Office 2000 i 2002/XP. Tworzenie własnych aplikacji w VBA
88 uklad okresowy_pierwiastkow
iqt_n_ptn_17_06_14 (4)
Fałszerstwa ewolucji. polish
2100. 3 класс. Урок 1.5 Арифметические действия над числами
Rewitalizacja vs recykling (Krzysztof Kalitko)
Mitsubishi Electric Księga Automatyzacji2014
Produkowanie koncentratów spożywczych
Koszty podgrzewania ciepłej wody użytkowej CWU
Restart raport końcowy
 
Sygnity S.A. WULKAN
Ad

Similar to Visual Basic .NET. Księga eksperta (20)

PDF
Microsoft Visual Basic .NET 2003. Księga eksperta
PDF
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcie
PDF
Visual Basic .NET. Ćwiczenia
PDF
Visual Basic .NET. Bazy danych. Księga eksperta
PDF
Excel. Programowanie dla profesjonalistów
PDF
JavaScript i DHTML. Receptury
PDF
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalisty
PDF
C# i ASP.NET. Szybki start
PDF
VB .NET. Almanach
PDF
Java. Usługi WWW. Vademecum profesjonalisty
PDF
Delphi 8 .NET. Kompendium programisty
PDF
Delphi 2005. 303 gotowe rozwiązania
PDF
Visual C# 2005 Express Edition. Od podstaw
PDF
Delphi dla .NET. Vademecum profesjonalisty
PDF
ASP.NET 2.0. Księga eksperta
PDF
AutoCAD 2002 i 2004. Tworzenie makr w VBA
PDF
C#. Programowanie
PDF
Programowanie. Od podstaw
PDF
Visio 2002 dla każdego
PDF
Spring. Zapiski programisty
Microsoft Visual Basic .NET 2003. Księga eksperta
Visual C# 2008. Projektowanie aplikacji. Pierwsze starcie
Visual Basic .NET. Ćwiczenia
Visual Basic .NET. Bazy danych. Księga eksperta
Excel. Programowanie dla profesjonalistów
JavaScript i DHTML. Receptury
MySQL. Budowanie interfejsów użytkownika. Vademecum profesjonalisty
C# i ASP.NET. Szybki start
VB .NET. Almanach
Java. Usługi WWW. Vademecum profesjonalisty
Delphi 8 .NET. Kompendium programisty
Delphi 2005. 303 gotowe rozwiązania
Visual C# 2005 Express Edition. Od podstaw
Delphi dla .NET. Vademecum profesjonalisty
ASP.NET 2.0. Księga eksperta
AutoCAD 2002 i 2004. Tworzenie makr w VBA
C#. Programowanie
Programowanie. Od podstaw
Visio 2002 dla każdego
Spring. Zapiski programisty

More from Wydawnictwo Helion (20)

PDF
Tworzenie filmów w Windows XP. Projekty
PDF
Blog, więcej niż internetowy pamiętnik
PDF
Access w biurze i nie tylko
PDF
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
PDF
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesie
PDF
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
PDF
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
PDF
Makrofotografia. Magia szczegółu
PDF
Windows PowerShell. Podstawy
PDF
Java. Efektywne programowanie. Wydanie II
PDF
JavaScript. Pierwsze starcie
PDF
Ajax, JavaScript i PHP. Intensywny trening
PDF
PowerPoint 2007 PL. Seria praktyk
PDF
Excel 2007 PL. Seria praktyk
PDF
Access 2007 PL. Seria praktyk
PDF
Word 2007 PL. Seria praktyk
PDF
Serwisy społecznościowe. Budowa, administracja i moderacja
PDF
AutoCAD 2008 i 2008 PL
PDF
Bazy danych. Pierwsze starcie
PDF
Inventor. Pierwsze kroki
Tworzenie filmów w Windows XP. Projekty
Blog, więcej niż internetowy pamiętnik
Access w biurze i nie tylko
Pozycjonowanie i optymalizacja stron WWW. Ćwiczenia praktyczne
E-wizerunek. Internet jako narzędzie kreowania image'u w biznesie
Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows
Co potrafi Twój iPhone? Podręcznik użytkownika. Wydanie II
Makrofotografia. Magia szczegółu
Windows PowerShell. Podstawy
Java. Efektywne programowanie. Wydanie II
JavaScript. Pierwsze starcie
Ajax, JavaScript i PHP. Intensywny trening
PowerPoint 2007 PL. Seria praktyk
Excel 2007 PL. Seria praktyk
Access 2007 PL. Seria praktyk
Word 2007 PL. Seria praktyk
Serwisy społecznościowe. Budowa, administracja i moderacja
AutoCAD 2008 i 2008 PL
Bazy danych. Pierwsze starcie
Inventor. Pierwsze kroki

Visual Basic .NET. Księga eksperta

  • 1. 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
  • 2. 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
  • 3. 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
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. 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.
  • 16. 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.
  • 17. 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.
  • 18. 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
  • 19. 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.
  • 20. 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.
  • 21. 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.
  • 22. 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.
  • 23. 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
  • 24. 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
  • 25. 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.
  • 26. 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.
  • 27. 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[
  • 28. 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.).
  • 29. 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
  • 30. 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:
  • 31. 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.
  • 32. 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.
  • 33. 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.
  • 34. 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[UVGOKCIPQUVKEUGDWIIGT*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[UVGOKCIPQUVKEU, 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ę
  • 35. 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.
  • 36. 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
  • 37. 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”).
  • 38. 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.
  • 39. 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 1DLGEVKURQUGF'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 +KURQUCDNGKURQUG 5VCVKE (KURQUGF #U $QQNGCP (CNUG +H (KURQUGF 6JGP 'ZKV 5WD (KURQUGF 6TWG %NQUG (#TTC[.KUV 0QVJKPI )%5WRRTGUU(KPCNKG /G 'PF 5WD Metoda KURQUG implementuje +KURQUCDNGKURQUG (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.
  • 40. 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.
  • 41. 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 #RRNKECVKQPQ'XGPVU 'PF 9JKNG
  • 42. 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 +KURQUCDNGKURQUG +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.).
  • 43. 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, 2TKPVCVG. 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.
  • 44. 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.
  • 45. 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.
  • 46. 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,
  • 47. 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 /WNVKECUVGNGICVG, 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
  • 48. 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
  • 49. 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
  • 50. 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
  • 51. 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
  • 52. 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ł.
  • 53. 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
  • 54. 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.
  • 55. 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”.
  • 56. 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 5KIPCNTCY. (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 IPCNTCY rysuje 5KIPCN jako 4GEVCPING (prostokąt) i wywołuje 5KIPCNTCY.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. .KIJVTCY 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.
  • 57. 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.
  • 58. 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.
  • 59. 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.