Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00424 007315 11067801 na godz. na dobę w sumie
C# i ASP.NET. Szybki start - książka
C# i ASP.NET. Szybki start - książka
Autor: Liczba stron: 456
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-389-7 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> c# - programowanie
Porównaj ceny (książka, ebook, audiobook).

Błyskawiczny kurs tworzenia aplikacji WWW w języku C#

C# to całkiem nowy język programowania zaprojektowany przez firmę Microsoft. Wygląda on jak mieszanka C++ i Javy, jest jednak tak prosty jak Visual Basic. Z jego pomocą można tworzyć aplikacje WWW i programy wyposażone w graficzny interfejs użytkownika. Język ten związany jest z platformą .NET, umożliwiającą tworzenie zaawansowanych aplikacji biznesowych działających w środowisku sieciowym, w tym także z technologią budowania dynamicznych serwisów internetowych ASP.NET. Programy działające na platformie .NET można pisać w wielu językach programowania, ale wiele wskazuje na to, że właśnie C# stanie się najpopularniejszym z nich.

Książka 'C# i ASP.NET. Szybki start' jest doskonałym podręcznikiem dla początkujących programistów. Jak każda pozycja z serii 'Szybki start', składa się z kilkudziesięciu rozdziałów, z których każdy przedstawia kolejne kroki, które należy wykonać, by osiągnąć zamierzony cel. Dodatkową zaletę stanowią liczne ilustracje.

Opisano między innymi:

Programista chcący tworzyć zaawansowane aplikacje internetowe ma wybór pomiędzy dwoma platformami: Java 2 EE Suna i .NET Microsoftu. Jeśli wybierze tę drugą, dzięki książce 'C# i ASP.NET. Szybki start' szybko będzie mógł tworzyć funkcjonalne aplikacje WWW w nowym, ekscytującym języku C#.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI C# i ASP.NET. Szybki start KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Autor: Jose Mojica T³umaczenie: Wojciech Moch (rozdz. 1 - 6), Rados³aw Meryk (rozdz. 7 - 13) ISBN: 83-7361-389-7 Tytu³ orygina³u: C# Web Development with ASP.NET: Visual QuickStart Guide Format: B5, stron: 456 Przyk³ady na ftp: 1127 kB C# to ca³kiem nowy jêzyk programowania zaprojektowany przez firmê Microsoft. Wygl¹da on jak mieszanka C++ i Javy, jest jednak tak prosty jak Visual Basic. Z jego pomoc¹ mo¿na tworzyæ aplikacje WWW i programy wyposa¿one w graficzny interfejs u¿ytkownika. Jêzyk ten zwi¹zany jest z platform¹ .NET, umo¿liwiaj¹c¹ tworzenie zaawansowanych aplikacji biznesowych dzia³aj¹cych w ġrodowisku sieciowym, w tym tak¿e z technologi¹ budowania dynamicznych serwisów internetowych ASP.NET. Programy dzia³aj¹ce na platformie .NET mo¿na pisaæ w wielu jêzykach programowania, ale wiele wskazuje na to, ¿e w³aġnie C# stanie siê najpopularniejszym z nich. Ksi¹¿ka „C# i ASP.NET. Szybki start” jest doskona³ym podrêcznikiem dla pocz¹tkuj¹cych programistów. Jak ka¿da pozycja z serii „Szybki start”, sk³ada siê z kilkudziesiêciu rozdzia³ów, z których ka¿dy przedstawia kolejne kroki, które nale¿y wykonaæ, by osi¹gn¹æ zamierzony cel. Dodatkow¹ zaletê stanowi¹ liczne ilustracje. Opisano miêdzy innymi: • Instalacjê niezbêdnego oprogramowania • Sk³adniki jêzyka C# • Instrukcje warunkowe i pêtle • Pracê z ci¹gami znaków • Programowanie obiektowe w C# • Korzystanie z tablic i kolekcji • Delegaty, zdarzenie, obs³ugê b³êdów • Tworzenie dynamicznych serwisów WWW w jêzyku C# Programista chc¹cy tworzyæ zaawansowane aplikacje internetowe ma wybór pomiêdzy dwoma platformami: Java 2 EE Suna i .NET Microsoftu. Jeġli wybierze tê drug¹, dziêki ksi¹¿ce „C# i ASP.NET. Szybki start” szybko bêdzie móg³ tworzyæ funkcjonalne aplikacje WWW w nowym, ekscytuj¹cym jêzyku C#. Spis treści Spis treści Wstęp 11 Rozdział 1. Zaczynamy 23 Jak zdobyć C# ...................................................ć........................................24 Instalowanie IIS...................................................ć......................................26 Tworzenie projektu aplikacji sieciowej w Visual Studio .NET ................28 Uruchamianie projektów sieciowych za pomocą Visual Studio .NET........ 31 Pisanie prostej strony ASP .NET ...................................................ć...........33 Wyszukiwanie błędów w aplikacjach ASP .NET .....................................35 Ręczne uruchamianie kompilatora ...................................................ć.........38 Kompilowanie i uruchamianie programów C# bez pomocy VS.NET ........ 39 Wyszukiwanie błędów w programach bez pomocy VS.NET ...................41 Rozdział 2. Składniki języka C# 43 Praca z elementami języka ...................................................ć.....................44 Pisanie kodu C#...................................................ć......................................48 Deklarowanie zmiennych ...................................................ć.......................50 Definiowanie stałych...................................................ć..............................53 Grupowanie stałych w typy wyliczeniowe................................................54 Deklarowanie funkcji ...................................................ć.............................56 Deklarowanie funkcji z parametrami ...................................................ć.....58 Zwracanie wartości funkcji ...................................................ć....................62 Definiowanie klas...................................................ć...................................64 Dodawanie klas do przykładowej aplikacji...............................................67 Tworzenie i stosowanie obiektów ...................................................ć..........68 Tworzenie obiektów w przykładowej aplikacji.........................................70 Włączanie definicji klas ze źródeł zewnętrznych......................................71 Grupowanie klas w przestrzeniach nazw ..................................................74 Dodawanie pól do klas ...................................................ć...........................78 Inicjalizowanie pól w momencie ich deklarowania ...................................79 Dodawanie właściwości do klas...................................................ć.............80 5 S p i s t r e ś c i Spis treści Dodawanie metod do klasy ...................................................ć....................86 Dodawanie składowych do klas przykładowego programu ......................89 Uruchamianie przykładowej aplikacji...................................................ć....90 Dodawanie komentarzy...................................................ć..........................95 Kierunki parametrów w typach referencyjnych ........................................97 Rozdział 3. Wyrażenia warunkowe i pętle 99 Praca z pętlami i warunkami ...................................................ć................ 100 Porównywanie typów numerycznych ...................................................ć.. 104 Porównywanie typów referencyjnych ...................................................ć.. 105 Łączenie porównań ...................................................ć.............................. 109 Instrukcje warunkowe ...................................................ć.......................... 110 Sprawdzanie wielu warunków za pomocą instrukcji switch ................... 112 Operator warunku...................................................ć................................. 114 Dodawanie instrukcji warunkowych do przykładowego programu ........ 115 Stosowanie pętli while ...................................................ć......................... 122 Stosowanie pętli do ...................................................ć.............................. 123 Stosowanie pętli for...................................................ć.............................. 124 Zakończenie i kontynuacja pętli...................................................ć........... 126 Dodawanie pętli do przykładowego programu........................................ 129 Rozdział 4. Ciągi znaków 133 Przygotowanie komputera do pracy z ciągami znaków .......................... 135 i c ś e r t s i p S Praca z ciągami znaków ...................................................ć....................... 137 Inicjalizowanie ciągów znaków ...................................................ć........... 140 Porównywanie ciągów znaków ...................................................ć............ 142 Łączenie ciągów znaków...................................................ć...................... 145 Określanie długości ciągu znaków ...................................................ć....... 147 Porównywanie i łączenie ciągów znaków w przykładowej aplikacji........ 148 Tworzenie ciągów z pojedynczych znaków ............................................ 151 Znaki specjalne...................................................ć..................................... 154 Stosowanie ciągów literałów...................................................ć................ 156 Dostęp do poszczególnych znaków ciągu ............................................... 158 Wyszukiwanie podciągów wewnątrz ciągów znaków ............................ 159 Pobieranie wycinka ciągu...................................................ć..................... 160 Dzielenie ciągu znaków...................................................ć........................ 161 Składanie ciągów...................................................ć.................................. 163 6 Spis treści Zamiana liter na małe lub wielkie ...................................................ć........ 164 Formatowanie ciągów znaków...................................................ć............. 165 Uruchomienie przykładowej aplikacji...................................................ć.. 166 Zamiana obiektów na ciągi znaków ...................................................ć..... 171 Tworzenie ciągów znaków za pomocą klasy StringBuilder ..................... 172 Rozdział 5. Dziedziczenie klas 173 Praca z dziedziczeniem klas ...................................................ć................. 174 Dziedziczenie z innej klasy ...................................................ć.................. 177 Udostępnianie składowych klas i ograniczanie dostępu do nich............. 180 Rozbudowa przykładowej aplikacji ...................................................ć..... 183 Ukrywanie metod klasy bazowej ...................................................ć......... 188 Pokrywanie funkcji w klasie wywiedzionej ............................................ 190 Dodawanie standardowego klawisza do przykładowej aplikacji ............ 194 Stosowanie nowego klawisza na formularzu WorkOrder ....................... 197 Dodawanie funkcji, które muszą zostać pokryte..................................... 200 Wymóg dziedziczenia ...................................................ć.......................... 201 Blokowanie dziedziczenia...................................................ć.................... 202 Rozdział 6. Składowe specjalne 203 Dodawanie wielu funkcji o takich samych nazwach, czyli przeciążanie funkcji...................................................ć..................... 204 Definiowane funkcji o zmiennej liczbie parametrów ................................. 207 Dodawanie konstruktorów ...................................................ć................... 209 Wywoływanie konstruktora klasy bazowej............................................. 210 Dodawanie finalizerów ...................................................ć........................ 212 Tworzenie bibliotek kodu za pomocą składowych statycznych.............. 213 Zmiana znaczenia operatora (przeciążanie operatorów) ......................... 216 Definiowanie równoważności klas przez przeciążenie operatora równości ...................................................ć............................... 220 Definiowanie równoważności klas przez pokrycie funkcji Equals ......... 222 Praca ze składowymi specjalnymi...................................................ć........ 224 Rozdział 7. Typy 229 Działania z typami...................................................ć................................ 230 Uzyskiwanie typu klasy ...................................................ć....................... 234 Sprawdzanie zgodności typów ...................................................ć............. 236 7 S p i s t r e ś c i Spis treści Konwersja jednego typu na inny ...................................................ć.......... 237 Rozwinięcie przykładowej aplikacji ...................................................ć.... 240 Definiowanie reguł konwersji (przeciążanie operatora konwersji) ........... 246 Rozdział 8. Interfejsy 249 Działania z interfejsami...................................................ć........................ 251 Definiowanie interfejsów ...................................................ć..................... 255 Niejawna implementacja składowych interfejsu ..................................... 257 Jawna implementacja składowych interfejsu .......................................... 260 Usprawnianie przykładowej aplikacji ...................................................ć.. 261 Wykorzystanie obiektów poprzez interfejsy ........................................... 268 Rozpoznawanie interfejsu ...................................................ć.................... 269 Wykorzystanie interfejsów do polimorfizmu.......................................... 271 Interfejs będący pochodną innego interfejsu........................................... 272 Refaktoryzacja...................................................ć...................................... 274 Ponowna implementacja interfejsów w klasie pochodnej....................... 275 Kończymy przykładową aplikację ...................................................ć....... 277 Rozdział 9. Tablice i kolekcje 279 Działania z tablicami i kolekcjami ...................................................ć....... 281 Tworzenie tablic wartości ...................................................ć.................... 285 Tworzenie tablic typów referencyjnych .................................................. 287 Poruszanie się po tablicy ...................................................ć...................... 291 Inicjowanie elementów tablicy w miejscu .............................................. 294 Tworzenie tablic wielowymiarowych ...................................................ć.. 296 Usprawnianie przykładowej aplikacji ...................................................ć.. 298 Odnajdywanie elementów tablicy za pomocą wyszukiwania liniowego...................................................ć....... 301 Sortowanie tablic...................................................ć.................................. 304 Odnajdywanie elementów tablicy za pomocą wyszukiwania binarnego...................................................ć....... 307 Klasy działające jak tablice (definiowanie indeksatorów) ...................... 309 Wprowadzenie indeksatorów do przykładowej aplikacji........................ 312 Kopiowanie tablic ...................................................ć................................ 313 Tworzenie list dynamicznych...................................................ć............... 314 Tworzenie kolejek ...................................................ć................................ 316 8 i c ś e r t s i p S Spis treści Tworzenie stosów...................................................ć................................. 317 Tworzenie tabel mieszających...................................................ć.............. 318 Przeglądanie elementów tabel mieszających........................................... 320 Kończymy przykładową aplikację ...................................................ć....... 321 Testowanie kontrolki CodeGridWeb...................................................ć.... 323 Rozdział 10. Delegaty i zdarzenia 325 Działania z delegatami i zdarzeniami...................................................ć... 327 Deklarowanie delegatów ...................................................ć...................... 330 Tworzenie i wywoływanie delegatów ...................................................ć.. 331 Łączenie delegatów ...................................................ć.............................. 333 Odłączanie delegatów ...................................................ć.......................... 334 Deklarowanie i wyzwalanie zdarzeń ...................................................ć.... 336 Deklarowanie zdarzeń przyjaznych dla WWW ...................................... 338 Subskrypcja zdarzeń...................................................ć............................. 340 Asynchroniczne wyzwalanie delegatów ................................................. 342 Oczekiwanie na zakończenie działania delegatów asynchronicznych ...... 346 Pobieranie wyników działania delegatów asynchronicznych ................. 348 Kończymy przykładową aplikację ...................................................ć....... 350 Rozdział 11. Obsługa błędów 353 S p i s t r e ś c i Wykonywanie działań z wyjątkami ...................................................ć..... 354 Przechwytywanie wyjątków...................................................ć................. 360 Przechwytywanie wybranych wyjątków ................................................. 363 Uzyskiwanie informacji o wyjątku...................................................ć....... 366 Działania z łańcuchami wyjątków...................................................ć........ 368 Deklarowanie własnych wyjątków...................................................ć....... 372 Definiowanie komunikatów o błędach...................................................ć. 374 Zgłaszanie wyjątku...................................................ć............................... 375 Przechwytywanie i ponowne zgłaszanie wyjątków ................................ 376 Tworzenie łańcucha wyjątków ...................................................ć............. 377 Wprowadzanie kodu, który wykonuje się przed zakończeniem działania funkcji ..................... 378 Zastosowanie słowa kluczowego using...................................................ć 380 Wprowadzanie zabezpieczeń formularzy do przykładowej aplikacji........ 382 Obsługa nieobsłużonych błędów w aplikacjach WWW ......................... 385 9 Spis treści Rozdział 12. Odbicia i atrybuty 389 Działania z odbiciami i atrybutami ...................................................ć...... 390 Identyfikacja kompilata...................................................ć........................ 394 Działania z wyświetlanymi nazwami ...................................................ć... 395 Działania z ciągami znaków opisu ścieżek ............................................. 398 Dynamiczne ładowanie programu na podstawie nazwy wyświetlanej...... 399 Dynamiczne ładowanie programu na podstawie ścieżki dostępu ........... 400 Tworzenie egzemplarza klasy w kompilacie........................................... 401 Uzyskiwanie listy klas w kompilacie ...................................................ć... 403 Wyszczególnienie składowych klasy ...................................................ć... 404 Dynamiczne ustawianie lub pobieranie pól............................................. 406 Dynamiczne wywoływanie metody ...................................................ć..... 409 Kończymy zadanie pierwsze w przykładowej aplikacji.......................... 411 Stosowanie atrybutów kodu ...................................................ć................. 413 Definiowanie atrybutów ...................................................ć....................... 414 Wyszukiwanie atrybutów w kodzie ...................................................ć..... 417 Kończymy zadanie drugie w przykładowej aplikacji.............................. 420 Rozdział 13. Projekty WWW w języku C# 423 Tworzenie projektu DLL za pomocą Visual Studio .NET ...................... 424 Odwoływanie się do kodu DLL i jego wykonywanie ............................. 428 Udostępnianie bibliotek DLL do globalnego wykorzystania .................. 429 Tworzenie serwisów WWW ...................................................ć................ 432 Wykorzystywanie serwisów WWW ...................................................ć.... 436 Skorowidz 439 i c ś e r t s i p S 10 Interfejsy Interfejsy Interfejsy Interfejsy to typy pozwalające na definiowanie wielu klas spełniających podobne funkcje. Wyobraźmy sobie klasę UEQTV. W klasie UEQTV są takie metody, jak: ,CFC, CVT[OCPKG, 1FVYCTCPKG/W[MK itp. Użytkownik jest zadowolony z klasy UEQTV, ponieważ umożliwia mu ona dojazdy do pracy i z powrotem. W pewnym momencie jego koledzy zaczęli jednak żartować z klasy UEQTV, dlatego postanowił zastąpić ją klasą (GTTCTK. Przed zastąpieniem klasy UEQTV klasą (GTTCTK użytkownik chce mieć jednak pewność, że klasa ta spełnia co najmniej takie same funkcje, co klasa Escort. Musi więc oferować metody ,CFC, CVT[OCPKG, 1FVYCTCPKG/W[MK. Wszystkie te działania mogą być wykonywane inaczej niż w klasie UEQTV, ale ważne jest, aby istniały co najmniej takie same metody. Ich zestaw nazywa się interfejsem. Interfejs może np. nosić nazwę +5COQEJQF. Wszystkie samochody, aby mogły być tak nazywane, będą musiały zawierać implementację interfejsu +5COQEJQF (przynajmniej z naszego punktu widzenia). W świecie, w którym żyjemy, obowiązują zasady interfejsów. Implementacjami podobnych interfejsów są, na przykład, .WFKG. Wielu z nas oddycha i je (jeśli ktoś się z tym nie zgadza, proszę natychmiast przestać czytać tę książkę). Każdy egzemplarz klasy .WFKG może w inny sposób oddychać lub jeść, ale, niezależnie od tego, takie firmy, jak np. McDonald będą mogły odnosić sukcesy tylko wtedy, gdy zostanie wykonana metoda ,GFGPKG należąca do interfejsu + NQYKGM. I n t e r f e j s y 249 Rozdział 8. W terminologii języka C# interfejsy są typami. W stosunku do definicji interfejsów w języku C++ różnią się tym, że nie są to wyspecjalizowane klasy. Są to natomiast oddzielne typy. Zgodnie z podstawową definicją, interfejs jest zbiorem definicji funkcji (tylko definicji, bez kodu implementacji). Funkcje te same w sobie nie wykonują żadnych działań. Przypominają interfejs + NQYKGM bez konkretnego egzemplarza człowieka — to tylko pojęcie, a nie rzeczywista implementacja. Aby można było skorzystać z interfejsu, należy go zaimplementować w obrębie klasy. Kiedy klasa implementuje interfejs, ogłasza wszem i wobec, że obsługuje wszystkie zdefiniowane w nim metody. Jeżeli sprzedawca używanych samochodów twierdzi, że jego towar jest implementacją interfejsu +5COQEJQF, to tak samo, jakby mówił, że zawiera co najmniej metody: ,CFC, CVT[OCPKG, 1FVYCTCPKG/W[MK. Jeżeli któraś z metod interfejsu nie zostanie zaimplementowana, kompilator języka C# zgłosi błąd. Zastosowanie interfejsów pozwala programistom pisać kod wykorzystujący funkcje i nie martwić się ich implementacją. Dzięki temu można rozpocząć od jakiejś implementacji, a potem całkowicie ją zastąpić bez konieczności przepisywania kodu. Sprawdza się to w przypadku interfejsu +5COQEJQF. Kierowcy nie uczą się prowadzenia konkretnego samochodu — uczą się prowadzić dowolny samochód, ponieważ wszystkie samochody realizują ten sam, podstawowy interfejs. Posłużmy się, jako przykładem rzeczywistego zastosowania interfejsów, technologią ADO .NET, która pozwala na realizację połączenia z bazą danych. Firma Microsoft, można w to wierzyć lub nie, nie ma zamiaru wymuszać użycia tylko jednej bazy danych. Zamiast zmuszać do użycia tego samego zestawu klas, zdefiniowała interfejs funkcji umożliwiających zrealizowanie połączenia z bazą danych. Producenci baz danych mają więc możliwość napisania klas będących implementacją tego interfejsu. Idea kodowania z wykorzystaniem interfejsów polega na tym, że można zmienić wykorzystywany pakiet bazy danych bez konieczności przepisywania aplikacji. 250 y s j e f r e t n I Interfejsy Działania z interfejsami Jako przykładową aplikację w tym rozdziale napiszemy moduł ASP .NET. Nie będzie to aplikacja bardzo rozbudowana, ale za to będzie ją można wykorzystać w rzeczywistych aplikacjach (w tym rozdziale nie będzie aplikacji dotyczącej supermenów). A zatem, czym jest moduł ASP .NET? Moduł jest klasą, która może przechwytywać żądania dowolnych stron w aplikacji. Moduły wykorzystuje się do wykonywania takich działań, jak np. testy zabezpieczeń. Mogą one przechwycić każde żądanie i albo je zatrzymać, albo kontynuować lub też zmodyfikować w pewien sposób. Moduły mogą także wykonywać działania po obsłudze żądania przez odpowiednią stronę. Programistom doświadczonym w programowaniu aplikacji WWW z pewnością pomoże wyjaśnienie, że moduły są odpowiednikiem filtrów IIS w środowisku .NET. Celem modułu, który utworzymy, będzie dostarczenie wszystkim stronom informacji o rozmiarach obszaru klienta w przeglądarce. Obszar klienta w przeglądarce to miejsce, w którym jest wyświetlana strona WWW (wewnątrz okna przeglądarki, bez pasków menu i stanu). Interesujące, że środowisko .NET nie przekazuje tych wymiarów za pośrednictwem żadnej z właściwości. Można jednak uzyskać te wielkości za pomocą skryptów działających po stronie serwera (VBScript lub JavaScript działające na komputerze-kliencie, a nie na serwerze tak, jak strony ASP). Można zapytać, dlaczego interesują nas te wymiary? Otóż są nam potrzebne, ponieważ czasami chcemy zastosować grafikę o mniejszych wymiarach, jeśli wymiary okna są mniejsze lub większych wymiarach, jeśli wymiary okna są większe. D z i a ł a n i a z i n t e r f e j s a m i 251 Rysunek 8.1. Do utworzenia modułu potrzebny jest tylko projekt biblioteki, a nie cały projekt WWW ASP .NET. Jednak utworzenie projektu WWW ASP .NET pozwala na napisanie i przetestowanie modułu w jednym projekcie Rozdział 8. Rozwiązanie problemu jest następujące. Kiedy klient zażąda strony po raz pierwszy, moduł zatrzyma żądanie i zwróci stronę z odpowiednim skryptem działającym po stronie klienta. Zadaniem skryptu będzie określenie wymiarów obszaru klienta. Skrypt zapisze wymiary w ukrytym polu, a następnie zażąda natychmiast tej samej strony, której klient żądał poprzednio. Wysłanie skryptu działającego po stronie klienta i zwrócenie pierwotnie żądanej strony powinno nastąpić na tyle szybko, aby użytkownik niczego nie zauważył. Za drugim razem, gdy moduł otrzyma żądanie tej samej strony (teraz zażąda jej skrypt działający po stronie klienta), moduł odnajdzie ukryte pola zawierające wymiary, utworzy niewielki obiekt służący do przechowywania potrzebnych informacji i przekaże je do żądanej strony. Strona pobierze obiekt z informacjami i zwróci wynik do klienta, który wykorzysta informacje o rozmiarze obszaru klienta. W naszym przypadku na stronie wymiary wyświetlone zostaną w polach tekstowych. Aby napisać moduł: 1. Uruchom Visual Studio .NET (Start/ Programy/Microsoft Visual Studio .NET). 2. Wybierz polecenie File/New/Project. Na ekranie pojawi się okno dialogowe New Project. 3. W panelu Project Types po lewej stronie okna New Project kliknij folder Visual C# projects. 4. Zaznacz ikonę ASP .NET Web Application i zmień nazwę aplikacji na interfacesproject (rysunek 8.1). 5. Program Visual Studio utworzy nowy projekt i otworzy formularz WebForm1.aspx. 6. Zmień nazwę formularza na dimensions.aspx. W tym celu wybierz polecenie View/Solution Explorer z górnego paska menu. i m a s j e f r e t n i z a i n a ł a i z D 252 Interfejsy 7. Kliknij prawym klawiszem myszy formularz dimensions.aspx i wybierz polecenie Properties. W tabelce właściwości, pokazanej poniżej na rysunku 8.2, zmień właściwość FileName z WebForm1.aspx na dimensions.aspx. 8. Zmodyfikuj formularz dimension.aspx w taki sposób, aby wyglądał tak, jak formularz pokazany na rysunku 8.3. Oczywiście, w ręczne wykonanie tego zadanie trzeba włożyć wiele pracy. Zamiast tego możesz wprowadzić kod HTML bezpośrednio w edytorze. Na rysunku 8.4, na następnej stronie, zaprezentowano kod HTML niezbędny do utworzenia formularza. Aby bezpośrednio wprowadzić kod HTML, kliknij przycisk HTML w oknie edytora. Alternatywnie możesz pobrać plik szkieletu dla tego projektu (patrz „Wskazówki” na następnej stronie). D z i a ł a n i a z i n t e r f e j s a m i 253 Rysunek 8.2. Zmiana nazwy pliku nie powinna sprawiać teraz żadnych problemów Rysunek 8.3. Bardzo prosty formularz, który łatwo utworzyć od nowa. Zawiera dwie etykiety, dwa pola tekstowe oraz jedno łącze Rozdział 8. Wskazówki  To, co do tej pory zrobiliśmy w przykładowej aplikacji, nie ma nic wspólnego z modułem użytkownika. Formularz projektowany w tym podrozdziale zostanie użyty do przetestowania modułu. Kod modułu zostanie dodany natychmiast po tym, jak dowiemy się czegoś na temat implementacji interfejsów.  Podobnie jak w przypadku innych projektów w tej książce, utworzenie projektu nie jest konieczne do poznania pojęć zaprezentowanych w niniejszym rozdziale.  Szkielety wszystkich projektów można pobrać z witryny WWW Wydawnictwa Peachpit pod adresem http://www.peachpit. com/vqs/csharp. i m a s j e f r e t n i z a i n a ł a i z D 254 Rysunek 8.4. Kod HTML pokazany na tym rysunku można wykorzystać jako wzorzec. Dzięki formularzowi możliwe jest uzyskanie informacji o wymiarach i pozycji wszystkich elementów sterujących  2CIGNCPIWCIGE QFGDGJKPFFKOGPUKQPUCURZEU #WVQ XGPV9KTGWRHCNUG +PJGTKVU KPVGTHCEGURTQLGEV9GD(QTO *6/. * # VKVNG 9GD(QTOVKVNG * # DQF[/5A215+6+10+0))TKF.C[QWV HQTOKF(QTOOGVJQFRQUV TWPCVUGTXGT CURNCDGNKFNDN9KFVJ UV[NG +0 :. (6 RZ 215+6+10CDUQNWVG612RZ TWPCVUGTXGT 5GTQMQħè CURNCDGN CURNCDGNKFNDN*GKIJV UV[NG +0 :. (6 RZ 215+6+10CDUQNWVG612RZ TWPCVUGTXGT 9[UQMQħè CURNCDGN CURVGZVDQZKFVZV9KFVJ UV[NG +0 :. (6 RZ 215+6+10CDUQNWVG612RZ TWPCVUGTXGT CURVGZVDQZ CURVGZVDQZKFVZV*GKIJV UV[NG +0 :. (6 RZ 215+6+10CDUQNWVG612RZ TWPCVUGTXGT CURVGZVDQZ CURJ[RGTNKPMKFNPM5GNH UV[NG +0 :. (6 RZ 215+6+10CDUQNWVG612RZ TWPCVUGTXGT 0CXKICVG7TNFKOGPUKQPUCURZ 1FħYKGľ CURJ[RGTNKPM HQTO DQF[ *6/. Tabela 8.1. Składowe interfejsu (składowe, które można wprowadzić do definicji interfejsu) Nazwa Metoda Właściwość Właściwość tylko do odczytu Indeks Zdarzenie Przykład UVTKPI/GVJQF  KPV#IG]IGVUGV_ KPV#IG]IGV_ NQPIVJKU=KPV KPFGZ?]IGVUGV_ GXGPV XGPV*CPFNGT 1P NKEM Rysunek 8.5. Składowe interfejsu to tylko definicje, które nie zawierają kodu. W definicjach nie stosuje się także modyfikatorów dostępu — wszystkie metody interfejsu są publiczne RWDNKEKPVGTHCEG+*WOCP ] UVTKPI0COG]IGV_właściwość tylko  do odczytu XQKF CV KPV#OQWPV metoda XQKF$TGCVJG metoda _ Interfejsy Definiowanie interfejsów Interfejsy definiuje się za pomocą słowa kluczowego KPVGTHCEG. Dla interfejsów można definiować metody, właściwości, delegaty, zdarzenia itp. Każdy z elementów wewnątrz interfejsu musi być jednak tylko deklaracją elementu i nie może zawierać implementacji. Aby zdefiniować interfejs: 1. Wpisz słowo kluczowe RWDNKE lub KPVGTPCN, w zależności od zasięgu, jaki ma mieć interfejs. 2. Wprowadź słowo kluczowe KPVGTHCEG, a po nim spację. 3. Wpisz nazwę interfejsu. 4. Otwórz nawias klamrowy ]. 5. Wprowadź definicje składowych (tabela 8.1). 6. Zamknij nawias klamrowy _ (rysunek 8.5). D e f i n i o w a n i e i n t e r f e j s ó w 255 Rozdział 8. Wskazówki  Wszystkie metody interfejsu z definicji są publiczne — w definicji metody nie można wprowadzić modyfikatorów dostępu (dotyczy to także modyfikatora RWDNKE).  Danych typu interfejsu można użyć w definicjach parametrów lub zmiennych (rysunek 8.6). W przypadku interfejsów nie można jednak tworzyć nowych egzemplarzy — na przykład nie można napisać PGY+#EEQWPV.  W interfejsach można przeciążać metody (rysunek 8.7).  Jeżeli jakiś programista użyje interfejsu, najlepiej nie zmieniać jego definicji. W przeciwnym razie istnieje ryzyko, że napisany program przestanie działać. W takiej sytuacji najlepiej zdefiniować nowy interfejs. Więcej informacji na ten temat znajdzie się w dalszej części tego rozdziału, w podrozdziale „Tworzenie interfejsów pochodnych od innych interfejsów”. w ó s j e f r e t n i e i n a w o i n i f e D Rysunek 8.6. Po zdefiniowaniu interfejsu można go wykorzystać jako typ danych w deklaracjach zmiennych lub parametrów ENCUU CKN[4QWVKPG ] XQKF6CUMU ] +*WOCPOCP +*WOCPYQOCP _ RWDNKEXQKF)Q6Q KPPGT +*WOCPRGTUQP ] RGTUQP CV  _ _ Rysunek 8.7. Przeciążanie metod to możliwość istnienia kilku metod o tej samej nazwie. Pamiętaj, że można to zrobić tylko pod warunkiem, że zmieni się liczbę parametrów lub zmodyfikuje typ jednego z nich RWDNKEKPVGTHCEG+*WOCP ] UVTKPI0COG]IGV_ właściwość tylko do odczytu XQKF CV KPV#OQWPV metoda XQKF CV UVTKPIHQQF6[RGKPV#OQWPV  przeciążanie _ 256 Rysunek 8.8. Implementacja interfejsu przypomina dziedziczenie. W przypadku metody niejawnej wystarczy zaimplementować składowe interfejsu jako metody publiczne RWDNKEKPVGTHCEG+*WOCP ] UVTKPI0COG]IGV_ XQKF5NGGR UJQTVJQWTU  _ RWDNKEENCUU2GTUQP+*WOCP ] RWDNKEUVTKPI0COG ] IGV ] TGVWTP2CWN _ _ RWDNKEXQKF5NGGR UJQTVJQWTU ] HQT UJQTVEQWPVGT EQWPVGTJQWTUEQWPVGT ] *VVR QPVGZVEQPVGZV *VVR QPVGZV WTTGPV EQPVGZV4GURQPUG9TKVG  JTCRKG  _ _ _ Interfejsy Niejawna implementacja składowych interfejsu Interfejsy są implementowane przez klasy. Zaimplementowanie interfejsu oznacza wprowadzenie kodu dla wszystkich zdefiniowanych w nim metod. Kompilator wymusza wprowadzenie kodu dla wszystkich metod bez wyjątku. Wynika to stąd, że programista wykorzystujący interfejs spodziewa się, że klasa implementująca interfejs będzie zawierać definicje wszystkich zawartych w nim metod. Istnieją dwa mechanizmy implementowania interfejsów w klasie: mechanizm niejawny i jawny. Najpierw zaprezentujemy mechanizm niejawny. Aby zaimplementować interfejs w sposób niejawny: 1. Po nazwie klasy, która będzie implementować interfejs, wpisz dwukropek, a po nim nazwę interfejsu, który będzie implementowany. 2. Wprowadź składowe odpowiadające wszystkim składowym interfejsu. 3. Oznacz metody implementacyjne jako publiczne. 4. Wpisz kod składowych interfejsu (rysunek 8.8). N i e j a w n a i m p l e m e n t a c j a s k ł a d o w y c h 257 Rozdział 8. Wskazówki  Ten mechanizm implementacji interfejsu cechuje wada polegająca na tym, że każdą metodę implementacyjną należy oznaczyć jako publiczną.  Aby zaimplementować więcej niż jeden interfejs, należy oddzielić poszczególne nazwy interfejsu przecinkiem (rysunek 8.9). h c y w o d a ł k s a j c a t n e m e l p m i a n w a j e i N 258 Rysunek 8.9. Klasa Person implementuje zarówno interfejs IHuman, jak i IManager. Zaimplementowanie interfejsu ustanawia relację „jest”. Innymi słowy, osoba (Person) jest człowiekiem (Human) i menedżerem (Manager) RWDNKEKPVGTHCEG+*WOCP ] UVTKPI0COG]IGV_ XQKF5NGGR UJQTVJQWTU  _ RWDNKEKPVGTHCEG+/CPCIGT ] XQKF5R[1P ORNQ[GG UVTKPIPCOGDQQN +U7PCYCTG  _ RWDNKEENCUU2GTUQP+*WOCP+/CPCIGT ] RWDNKEUVTKPI0COG ] IGV ] TGVWTP2CWN _ _ RWDNKEXQKF5NGGR UJQTVJQWTU ] HQT UJQTVEQWPVGT EQWPVGTJQWTUEQWPVGT ] *VVR QPVGZVEQPVGZV *VVR QPVGZV WTTGPV EQPVGZV4GURQPUG9TKVG  JTCRKG  _ _ RWDNKEXQKF5R[1P ORNQ[GG UVTKPIPCOG DQQN+U7PCYCTG ] YJKNG +U7PCYCTG ] .QQM1XGT5JQWNFGT PCOG  _ _ _ Rysunek 8.10. W powyższym kodzie zdefiniowano klasę Person, która implementuje interfejs IHuman. Następnie, biorąc pod uwagę to, że nie wszystkie osoby są menedżerami, zdefiniowano klasę opisującą menedżerów. Jednak, ze względu na to, że menedżerowie są ludźmi (persons), klasa ta dziedziczy wszystkie składowe klasy Person (zasada dziedziczenia). Na końcu znajduje się implementacja interfejsu IManager RWDNKEKPVGTHCEG+*WOCP ] UVTKPI0COG]IGV_ XQKF5NGGR UJQTVJQWTU  _ RWDNKEKPVGTHCEG+/CPCIGT ] XQKF5R[1P ORNQ[GG UVTKPIPCOGDQQN +U7PCYCTG  _ RWDNKEENCUU2GTUQP+*WOCP ] RWDNKEUVTKPI0COG ] IGV ] TGVWTP2CWN _ _ RWDNKEXQKF5NGGR UJQTVJQWTU ] HQT UJQTVEQWPVGT EQWPVGTJQWTUEQWPVGT ] *VVR QPVGZVEQPVGZV *VVR QPVGZV WTTGPV EQPVGZV4GURQPUG9TKVG  JTCRKG  _ _ _ RWDNKEENCUU/CPCIGT2GTUQP+/CPCIGT RWDNKEXQKF5R[1P ORNQ[GG UVTKPIPCOG DQQN+U7PCYCTG ] YJKNG +U7PCYCTG ] .QQM1XGT5JQWNFGT PCOG  _ _ _ Interfejsy  Jeżeli klasa jest pochodną innej klasy (nie interfejsu), najpierw należy wymienić klasę, która nie należy do interfejsu, a następnie implementowane interfejsy. Wszystkie te elementy trzeba oddzielić przecinkami (rysunek 8.10). N i e j a w n a i m p l e m e n t a c j a s k ł a d o w y c h 259 Rysunek 8.11. W przypadku jawnego implementowania interfejsu nie wprowadza się modyfikatorów dostępu. Należy wpisać nazwę interfejsu, po nim kropkę, a po niej nazwę metody RWDNKEKPVGTHCEG+*WOCP ] UVTKPI0COG]IGV_ XQKF5NGGR UJQTVJQWTU  _ RWDNKEENCUU2GTUQP+*WOCP ] UVTKPI+*WOCP0COG ] IGV ] TGVWTP2CWN _ _ XQKF+*WOCP5NGGR UJQTVJQWTU ] HQT UJQTVEQWPVGT EQWPVGTJQWTUEQWPVGT ] *VVR QPVGZVEQPVGZV *VVR QPVGZV WTTGPV EQPVGZV4GURQPUG9TKVG  JTCRKG  _ _ _ Rozdział 8. Jawna implementacja składowych interfejsu Podczas implementowania interfejsu przez wprowadzanie składowych publicznych powstaje problem polegający na tym, że czasami dwa interfejsy zawierają metodę o takiej samej nazwie i takich samych parametrach, ale konieczne jest zaimplementowanie tych metod na dwa różne sposoby. W przypadku zastosowania metody niejawnej jedna metoda publiczna będzie stanowiła implementację metod o takiej samej nazwie i tym samym zbiorze parametrów dla wszystkich interfejsów. Metoda jawna umożliwia poinformowanie kompilatora o tym, którą metodę, którego interfejsu mieliśmy zamiar zaimplementować. Aby jawnie zaimplementować interfejs: 1. Po nazwie klasy, która będzie implementować interfejs, wpisz dwukropek, a po nim nazwę interfejsu, który będzie implementowany. 2. Wpisz typ zwracanej wartości dla składowej interfejsu. 3. Wpisz +0CYC+PVGTHGLUW/GVQFC+PVGTHGLUW. Mówiąc inaczej, wpisz nazwę interfejsu, po nim kropkę, a po niej nazwę metody interfejsu. 4. Wprowadź parametry składowej interfejsu. 5. Wpisz kod składowej interfejsu (rysunek 8.11). Wskazówka  Wszystkie metody implementowane w ten sposób są prywatne. Nie można wprowadzić modyfikatora dostępu na początku definicji. h c y w o d a ł k s a j c a t n e m e l p m i a n w a J 260 Interfejsy Usprawnianie przykładowej aplikacji Teraz, kiedy wiemy już, w jaki sposób definiuje się interfejsy oraz jak należy implementować interfejsy za pomocą klas, czas usprawnić przykładową aplikację. Dokładniej rzecz ujmując, zdefiniujemy klasę, która będzie służyć jako moduł użytkownika. Aby przekształcić klasę w moduł, należy zaimplementować w niej interfejs 5[UVGO9GD+*VVR/QFWNG. Jego zaimplementowanie nie jest trudne — zawiera tylko dwie metody: +PKV i KURQUG. Środowisko ASP .NET wywołuje metodę +PKV w momencie, gdy moduł jest po raz pierwszy ładowany do pamięci. Metoda KURQUG wywoływana jest w momencie usuwania modułu z pamięci. Jedyna trudność polega na wykorzystaniu zdarzenia. Zdarzenia zostaną opisane w rozdziale 10. „Delegaty i zdarzenia”. Nie zamierzamy poświęcać w tym rozdziale wiele miejsca na tłumaczenie, czym jest zdarzenie. Na razie wystarczy, abyśmy wiedzieli, że zdarzenie jest metodą wywoływaną w wyniku działania. Implementacja zdarzeń pod wieloma względami przypomina implementację interfejsów. Różnica polega na tym, że interfejs może zawierać kilka metod, natomiast zdarzenie zawiera tylko jedną metodę. Przykładem zdarzenia jest kliknięcie przycisku. Klasa żąda od zdarzenia ENKEM informacji od przycisku formularza. Kiedy użytkownik kliknie przycisk, serwer informuje klasę, że miało miejsce zdarzenie. Moduł można wykorzystać np. do nasłuchiwania wystąpienia zdarzenia $GIKP4GSWGUV. Środowisko ASP .NET wyzwala to zdarzenie za każdym razem, gdy przeglądarka klienta zażąda strony. U s p r a w n i a n i e p r z y k ł a d o w e j a p l i k a c j i 261 Rozdział 8. Aby zdefiniować klasę modułu użytkownika: 1. Z paska menu wybierz polecenie Project/ Add class. Wpisz custommodule.cs jako nazwę klasy i wciśnij Enter (rysunek 8.12). 2. W górnej części kodu modułu, poniżej wiersza o treści WUKPI5[UVGO, wpisz wiersz WUKPI5[UVGO9GD. 3. W wierszu w postaci: RWDNKEENCUU EWUVQOOQFWNG dodaj na końcu: +*VVR/QFWNG tak, aby wiersz ten przyjął postać: RWDNKE ENCUUEWUVQOOQFWNG+*VVR/QFWNG. 4. Teraz trzeba trochę „pooszukiwać”. W systemie Visual Studio .NET znajduje się kreator pozwalający na łatwą implementację interfejsu. Z menu wybierz polecenie View/Class View. 5. W oknie Class View rozwiń folder interfacesproject/custommodule/Bases and interfaces. Kliknij prawym klawiszem myszy IHttpModule i z rozwijanego menu wybierz Add/Implement Interface (rysunek 8.13). i j c a k i l p a j e w o d a ł k y z r p e i n a i n w a r p s U 262 Rysunek 8.12. Wszystkie właściwości funkcjonalne modułu użytkownika zostaną zaimplementowane w klasie custommodule. Dzięki wykorzystaniu okna dialogowego pokazanego na rysunku użyjemy kreatora do wygenerowania szkieletu klasy Rysunek 8.13. Kreator implementacji interfejsu wykorzystuje mechanizm niejawnej implementacji. Dla każdej składowej interfejsu definiowane są elementy publiczne Interfejsy Rysunek 8.14. Interfejs IHttpModule spełnia dwie funkcje. Po pierwsze, informuje środowisko ASP .NET, że klasa jest modułem użytkownika. Po drugie, środowisko zyskuje możliwość poinformowania klasy, kiedy moduł jest ładowany po raz pierwszy (metoda Init) oraz kiedy nie jest już potrzebny (metoda Dispose) 6. Kreator spowoduje dodanie namiastek metod +PKV i KURQUG. Kod przyjmie postać widoczną na rysunku 8.14. 7. Dodaj do klasy metodę $GIKP4GSWGUV (rysunek 8.15). WUKPI5[UVGO WUKPI5[UVGO9GD PCOGURCEGKPVGTHCEGURTQLGEV ] UWOOCT[  Ogólny opis modułu custommodule UWOOCT[ RWDNKEENCUUEWUVQOOQFWNG+*VVR/QFWNG ] RWDNKEEWUVQOOQFWNG ]   DO ZROBIENIA: Tutaj należy wprowadzić logikę konstruktora  _ TGIKQP+ORNGOGPVCVKQPQH+*VVR/QFWNG RWDNKEXQKF +PKV 5[UVGO9GD*VVR#RRNKECVKQPEQPVGZV ] _ RWDNKEXQKF KURQUG ] _ GPFTGIKQP _ _ U s p r a w n i a n i e p r z y k ł a d o w e j a p l i k a c j i Rysunek 8.15. Metoda BeginRequest nie jest częścią interfejsu IHttpModule. Jest to zdarzenie zdefiniowane dla klasy HttpApplication, informujące o tym, że występują żądania do dowolnej ze stron w aplikacji WUKPI5[UVGO WUKPI5[UVGO9GD PCOGURCEGKPVGTHCEGURTQLGEV ] UWOOCT[  Ogólny opis modułu custommodule UWOOCT[ RWDNKEENCUUEWUVQOOQFWNG+*VVR/QFWNG ] RWDNKEEWUVQOOQFWNG ]   DO ZROBIENIA: Tutaj należy wprowadzić logikę konstruktora  _ TGIKQP+ORNGOGPVCVKQPQH+*VVR/QFWNG RWDNKEXQKF +PKV 5[UVGO9GD*VVR#RRNKECVKQPEQPVGZV ] _ RWDNKEXQKF KURQUG ] _ GPFTGIKQP XQKF$GIKP4GSWGUV QDLGEVUGPFGT  XGPV#TIUCTIU ] _ _ _ 263 Rozdział 8. 8. W metodzie +PKV wprowadź kod wiążący zdarzenie $GIKP4GSWGUV z metodą klasy $GIKP4GSWGUV (rysunek 8.16). Nie martw się, jeżeli na razie kod ten jest niejasny, jego szczegółowe wyjaśnienie znajdzie się w rozdziale 10. „Delegaty i zdarzenia”. Rysunek 8.16. Zwróć uwagę, że w celu powiązania zdarzenia klasy z metodą do zdarzenia odwołujemy się w taki sposób, jakby było ono właściwością obiektu (obiekt.nazwazdarzenia), następnie używamy operatora += i przypisujemy mu nowy obiekt (delegat). Metodę przekazujemy jako parametr konstruktora obiektu WUKPI5[UVGO WUKPI5[UVGO9GD PCOGURCEGKPVGTHCEGURTQLGEV ] UWOOCT[ 1IÎNP[QRKUOQFWđWEWUVQOOQFWNG UWOOCT[ RWDNKEENCUUEWUVQOOQFWNG+*VVR/QFWNG ] RWDNKEEWUVQOOQFWNG ]  DO ZROBIENIA: Tutaj należy wprowadzić logikę konstruktora  _ TGIKQP+ORNGOGPVCVKQPQH+*VVR/QFWNG RWDNKEXQKF +PKV 5[UVGO9GD*VVR#RRNKECVKQPEQPVGZV ] EQPVGZV$GIKP4GSWGUV PGY  XGPV*CPFNGT $GIKP4GSWGUV  _ RWDNKEXQKF KURQUG ] _ GPFTGIKQP XQKF$GIKP4GSWGUV QDLGEVUGPFGT  XGPV#TIUCTIU ] _ _ _ i j c a k i l p a j e w o d a ł k y z r p e i n a i n w a r p s U 264 Rysunek 8.17. Doceń piękno literałów znakowych. Zwróć uwagę, jak łatwo — korzystając z literałów znakowych — można umieścić znaki końca wiersza w ciągu znaków. Po prostu formatujemy ciąg znaków, tak jak chcemy, umieszczając gdzie należy znaki końca wiersza RWDNKEXQKF+PKV 5[UVGO9GD*VVR#RRNKECVKQP EQPVGZV ] EQPVGZV$GIKP4GSWGUV PGY XGPV*CPFNGT $GIKP4GSWGUV  UVTKPIJVON  JVON ĐCFQYCPKG UETKRVNCPIWCIGXDUETKRV 5WD)GV KOGPUKQPU  KOENKGPV9KFVJ  KOENKGPV*GKIJV ENKGPV9KFVJFQEWOGPVDQF[ NKGPV9KFVJ ENKGPV*GKIJV FQEWOGPVDQF[ NKGPV*GKIJV FQEWOGPVO[HQTOVZV KOGPUKQPU8CNWG ENKGPV9KFVJENKGPV*GKIJV  FQEWOGPVO[HQTOUWDOKV  PF5WD UETKRV DQF[QP.QCF)GV KOGPUKQPU HQTOPCOGO[HQTOOGVJQF2156 CEVKQP]_ R KPRWVV[RGJKFFGP PCOGVZV KOGPUKQPU UKG R HQTO DQF[ JVON  EQPVGZV#RRNKECVKQP=AA KUEQXGT*6/.?JVON _ Interfejsy 9. Wprowadź kod w metodzie +PKV w celu utworzenia ciągu znaków stanowiącego skrypt działający po stronie klienta i zapisz go w obiekcie #RRNKECVKQP. Pamiętaj, że obiekt #RRNKECVKQP jest dostępny na wszystkich stronach i dla każdego klienta (rysunek 8.17). U s p r a w n i a n i e p r z y k ł a d o w e j a p l i k a c j i 265 Rysunek 8.18. Na tym rysunku znalazł się kod, który wymaga wyjaśnienia. Szczegółowe informacje na jego temat można znaleźć w ramce pt. „Szczegóły zdarzenia BeginRequest” XQKF$GIKP4GSWGUV QDLGEVUGPFGT XGPV#TIU CTIU ] )NQDCNI )NQDCN UGPFGT UVTKPIFKOGPUKQPU I4GSWGUV(QTO=VZV KOGPUKQPU? KH FKOGPUKQPUPWNN^^FKOGPUKQPU  ] UVTKPIJVON UVTKPI I QPVGZV å#RRNKECVKQP=AA KUEQXGT*6/.? UVTKPIPGY7TNUVTKPI(QTOCV JVON I4GSWGUV7TN#DUQNWVG2CVJ  I4GURQPUG9TKVG PGY7TN  I QORNGVG4GSWGUV  _ GNUGKH  FKOGPUKQPU+PFGZ1H  NKGPV9KFVJ  ] UVTKPI=?UKGUFKOGPUKQPU5RNKV   KPVENKGPV9KFVJ5[UVGO QPXGTV 6Q+PV UKGU=?  KPVENKGPV*GKIJV 5[UVGO QPXGTV6Q+PV UKGU=?  I QPVGZV+VGOU=AA NKGPV9KFVJ? ENKGPV9KFVJ I QPVGZV+VGOU=AA NKGPV*GKIJV? ENKGPV*GKIJV _ _ Rysunek 8.19. Instrukcja #region powoduje dodanie obszaru rozwijanego kodu. Kiedy edytor wykryje dyrektywę #region, umieszcza znak minus po lewej stronie okna kodu Rozdział 8. 10. Teraz, w treści metody $GIKP4GSWGUV wpisz kod pokazany na rysunku 8.18. Zadaniem tego kodu jest sprawdzenie, czy są dostępne informacje o wymiarach. Informacje te powinny być dostępne za pośrednictwem pola ukrytego. Jeżeli pole tekstowe nie istnieje, moduł zablokuje żądanie strony i wyśle skrypt działający po stronie klienta. Skrypt zarejestruje wymiary okna w ukrytym polu i natychmiast zażąda strony ponownie. Moduł sprawdzi, czy pole tekstowe istnieje i, jeżeli istnieje, wprowadzi wymiary do obiektu +VGO (więcej informacji na ten temat znajdzie się w ramce na następnej stronie). Wskazówki  Kod zaprezentowany w tym podrozdziale to kompletny kod potrzebny do utworzenia modułu użytkownika. Jednak moduł ten nie będzie działać dopóty, dopóki nie uzupełnimy przykładu kodem pokazanym w dalszej części tego rozdziału.  Kreator implementujący interfejsy wprowadza kod TGIKQP+ORNGOGPVCVKQPQH+*VVR/QFWNG na początku bloku metod implementacyjnych oraz GPFTGIKQP na końcu tego bloku. Te instrukcje nie dotyczą bezpośrednio kompilatora. Umożliwiają one uzyskanie rozwijanego kodu w edytorze. Jak można zauważyć, w edytorze pojawi się znak minus z lewej strony deklaracji regionu (rysunek 8.19). Kliknięcie znaku minus w edytorze spowoduje ukrycie kodu umieszczonego w obszarze i zastąpienie znaku minus plusem (rysunek 8.20). Kliknięcie znaku plus spowoduje ponowne pojawienie się kodu. i j c a k i l p a j e w o d a ł k y z r p e i n a i n w a r p s U Rysunek 8.20. Kliknięcie znaku minus powoduje rozwinięcie kodu obszaru i wyświetlenie opisu za słowem #region, umożliwiającego identyfikację kodu. Słowo kluczowe #region w kodzie nie ma żadnego znaczenia funkcjonalnego. Jest ono wykorzystywane wyłącznie przez edytor, zatem, jeżeli komuś wydaje sinę niepotrzebne, może je usunąć 266 Interfejsy Szczegóły zdarzenia BeginRequest W pierwszym wierszu metody $GIKP4GSWGUV znajduje się instrukcja konwersji obiektu UGPFGT (pierwszy parametr metody) na obiekt )NQDCN. )NQDCN jest klasą generowaną przez kreator podczas tworzenia projektu ASP .NET. Jest to pochodna yklasy *VVR#RRNKECVKQP. Obiekt tej klasy tworzy się za pierwszym razem, gdy dowolny klient sykorzysta z dowolnej strony w aplikacji. Z obiektu )NQDCN można uzyskać dostęp do innych obiektów — np. 4GURQPUG lub 4GSWGUV. W drugim wierszu kodu użyto obiektu )NQDCN do uzyskania obiektu 4GSWGUV. Jak pamiętamy, obiekt 4GSWGUV umożliwia uzyskanie informacji na temat żądania kliyenta. Jeżeli skorzystamy z właściwości (QTO, możemy uzyskać dostęp do ukrytego pola, które zostałoy utworzone przez skrypt działający po stronie klienta. Nazwa teygo ukrytego pola to VZV KOGPUKQPU. W wierszu I4GSWGUV(QTO=VZV KOGPUKQPU? następuje pobranie tekstu z ukrytego pola. Jeżeli pole nie istnieje, zwrócony wynik będzie wartoyścią PWNN. W przeciwnym razie będą to współrzędne obszaru klienta. Skrypt działający po ystronie klienta zapisuje współrzędne w postaci: szerokość;wysokość (np. 800;600). Jeżeli wynik wynosi PWNN, do klienta wysyłany jest skrypt za pomocą funkcji 4GURQPUG9TKVG. Potem następuje wywołanie funkcji QORNGVG4GSWGUV, której działanie polega na zatrzymaniu żądania stroyny. Jeżeli wymiary są dostępne, następuje rozbicie ciągu znaków o formacie yszerokość;wysokość na dwie liczby i konwersja tych liczb na typ KPVGIGT. Wartości te są następnie umieszczone w obiekcie +VGOU. Do tej pory nie używaliśmy obiektu +VGOU, ale przypomina on obiekty 5GUUKQP oraz #RRNKECVKQP. Ogólnie rzecz biorąc, jest to jeszcze jeden sposób utrywalania informacji. Różnica między tymi obiektami polega na czasie dostępności informacyji. W obiekcie +VGOU informacje są dostępne tylko na czas trwania żądania klienta. W pyrzypadku obiektu #RRNKECVKQP informacje są dostępne tak długo, jak serwer WWW przetwarza aplikację i mają do nich dostęp wszystkie klienty korzystające z aplikacji. Informacje zapisanye w obiekcie 5GUUKQP są dostępne na czas trwania programu, ale są one specyficzne dla każdego yklienta. Obiekt +VGOU istnieje tylko na czas żądania. Jeżeli zatem klient przechodzi z jedynej strony na drugą, informacje zostają utracone. W ramach tego samego żądania moduł może jedynak umieścić informacje w obiekcie +VGOU i strona będzie miała do nich dostęp przez odwołaniey I QPVGZV+VGOU. U s p r a w n i a n i e p r z y k ł a d o w e j a p l i k a c j i 267 Rozdział 8. Wykorzystanie obiektów poprzez interfejsy Kiedy programista zdefiniuje interfejs i zaimplementuje go jako konkretną klasę, może używać tej klasy poprzez interfejs. Aby używać klasy poprzez interfejs: 1. Zdefiniuj zmienną typu interfejsu. Wpisz na przykład + CTXCT. 2. Ustaw zmienną typu interfejsu na wartość równą klasie, która ten interfejs implementuje. Wpisz na przykład PGY UEQTV (rysunek 8.21). Wskazówka  Nie można tworzyć egzemplarzy interfejsu. Interfejs jest typem abstrakcyjnym, co oznacza, że nie jest to klasa, której obiekty można utworzyć. Zamiast tego tworzy się egzemplarze klasy implementującej interfejs. w ó t k e i b o e i n a t s y z r o k y W Rysunek 8.21. Chociaż typem zmiennej jest ICar, nie można napisać new ICar. Trzeba utworzyć egzemplarz klasy implementującej interfejs. Nie można tworzyć egzemplarzy interfejsu KPVGTHCEG+ CT ] UVTKPI4WP  UVTKPI5VQR  UVTKPI2NC[/WUKE  _ ENCUU UEQTV+ CT ] RWDNKEUVTKPI4WP ] TGVWTP,CFúVCMU[DMQLCMWOKGO _ RWDNKEUVTKPI5VQR ] TGVWTP,CMFQDTG9TGUEKGUKúOQIú CVT[OCè _ RWDNKEUVTKPI2NC[/WUKE ] TGVWTP,GUVGħO[RKTCVCOKMVÎT[PKE PKGTQDKæ _ _ ENCUU TKXGT ] RWDNKEUVTKPI)Q6Q9QTM ] + CTECTPGY UEQTV  UVTKPIOUI OUI ECT4WP  OUI ECT2NC[/WUKE  OUI ECT5VQR  TGVWTPOUI _ _ 268 Rysunek 8.22. Zmienna obj jest typu object. Oznacza to, że może wskazywać na obiekt Cat lub na obiekt Dog. Powyższy kod testuje zawartość zmiennej obj przez sprawdzenie, czy obiekt obj obsługuje interfejs IDog KPVGTHCEG+ CV ] UVTKPI+IPQTG1YPGT  _ KPVGTHCEG+ QI ] UVTKPI.KUVGP6Q1YPGT  _ ENCUU2QQFNG+ QI ] _ ENCUU5KCOGUG+ CV ] _ ENCUU1YPGT ] XQKF(GGF#PKOCN QDLGEVQDL ] KH QDLKU+ QI ] + QIFQI + QI QDL UVTKPIEOFFQI.KUVGP6Q1YPGT  _ _ _ Interfejsy Rozpoznawanie interfejsu Przed użyciem obiektu poprzez interfejs warto sprawdzić, czy obiekt rzeczywiście obsługuje interfejs. Oczywiście, jeżeli mamy dostęp do definicji klasy, możemy na nią spojrzeć i przekonać się, czy klasa implementuje interfejs. Czasami jednak mamy do czynienia z danymi typu QDLGEV, dla których trzeba zweryfikować, czy obiekt, na który wskazuje zmienna, jest zgodny z interfejsem, którego chcemy użyć. Istnieją dwa sposoby sprawdzenia, czy obiekt obsługuje interfejs. Aby sprawdzić, czy obiekt obsługuje interfejs: 1. Wpisz KH QDLKU+#P[VJKPI , gdzie QDL jest zmienną wskazującą na obiekt, który chcesz sprawdzić, natomiast +#P[VJKPI jest nazwą interfejsu, dla którego chcesz przeprowadzić test (rysunek 8.22). lub Wpisz +#P[VJKPIXCTQDLCU +#P[VJKPI, gdzie +#P[VJKPI jest interfejsem, dla którego chcesz przeprowadzić test, XCT jest dowolną zmienną służącą do przechowywania odwołania do obiektu, a QDL jest obiektem, który chcesz sprawdzić. R o z p o z n a w a n i e i n t e r f e j s u 269 Rozdział 8. 2. Wpisz instrukcję KH XCTPWNN . Jeżeli po wykonaniu pierwszego kroku zmienna XCT jest równa null, obiekt nie obsługuje interfejsu. Jeśli test zwróci wartość różną od null, obiekt obsługuje interfejs, a zmienna XCT wskazuje na odwołanie do interfejsu (rysunek 8.23). Wskazówki  Podczas korzystania z pierwszego mechanizmu, po uzyskaniu informacji, że obiekt obsługuje interfejs, aby użyć obiektu poprzez interfejs, należy zadeklarować zmienną typu interfejsu, po czym dokonać konwersji obiektu na interfejs.  W przypadku drugiego mechanizmu rozpoznawania interfejsu, zarówno konwersja obiektu, jak i rozpoznanie następuje w jednym kroku. Jeżeli obiekt obsługuje interfejs, zmienna XCT będzie wskazywać na obiekt, w przeciwnym razie zmienna XCT przyjmie wartość null.  Istnieje trzeci mechanizm rozpoznawania, czy obiekt obsługuje interfejs. Można spróbować dokonać konwersji obiektu na interfejs. Jeżeli obiekt nie obsługuje interfejsu, konwersja spowoduje zgłoszenie wyjątku (błędu). Wyjątki zostaną omówione w rozdziale 11. „Obsługa błędów”. Wykorzystywanie wyjątków nie jest zalecane jako sposób rozpoznawania obsługi interfejsu przez obiekty, ponieważ wyjątki mogą wpłynąć niekorzystnie na wydajność działania programu. u s j e f r e t n i e i n a w a n z o p z o R Rysunek 8.23. Kiedy do sprawdzenia, czy obiekt obsługuje interfejs, użyjemy polecenia as, uzyskamy wynik null wtedy, gdy obiekt go nie obsługuje KPVGTHCEG+ CV ] UVTKPI+IPQTG1YPGT  _ KPVGTHCEG+ QI ] UVTKPI.KUVGP6Q1YPGT  _ ENCUU2QQFNG+ QI ] _ ENCUU5KCOGUG+ CV ] _ ENCUU1YPGT ] XQKF(GGF#PKOCN QDLGEVQDL ] + QIFQIQDLCU+ QI KH FQIPWNN UVTKPIEOFFQI.KUVGP6Q1YPGT  _ _ 270 Rysunek 8.24. Zwróć uwagę, że typem parametru metody Communicate jest IHuman. Do metody można przekazać dowolny obiekt, który implementuje interfejs. Każda z trzech klas implementuje interfejs w inny sposób. Metoda Communicate zwraca inny ciąg znaków w zależności od przekazanego obiektu KPVGTHCEG+JWOCP ] UVTKPI5RGCM  _ ENCUU$CD[+*WOCP ] RWDNKEUVTKPI5RGCM ] TGVWTP)QQIQQICCICC _ _ ENCUU5RQWUG+*WOCP ] RWDNKEUVTKPI5RGCM ] TGVWTP [OQIúMWRKèPQY[MQORWVGT! _ _ ENCUU(TKGPF+*WOCP ] RWDNKEUVTKPI5RGCM ] TGVWTP [OÎIđD[ħRQľ[E[èOKVTQEJú RKGPKúF[! _ _ ENCUU2GTUQP ] UVTKPI QOOWPKECVG +*WOCPRGTUQP ] TGVWTPRGTUQP5RGCM  _ XQKF CKN[.KXKPI ] UVTKPICPUYGT 5RQWUGURPGY5RQWUG  CPUYGT QOOWPKECVG UR  (TKGPFHTPGY(TKGPF  CPUYGT QOOWPKECVG HT  $CD[DCPGY$CD[  CPUYGT QOOWPKECVG DC  _ _ Interfejsy Wykorzystanie interfejsów do polimorfizmu Polimorfizm to mechanizm polegający na tym, że dwie powiązane ze sobą klasy mają nieznacznie różniące się implementacje tej samej metody. W przypadku wykorzystania interfejsów jako typów, programista może zdefiniować funkcje, które akceptują jako parametry dowolne obiekty implementujące interfejs. Następnie, w zależności od obiektu przesłanego do funkcji, wykonywany jest nieco inny kod. Aby wykorzystać polimorfizm: 1. W dowolnej klasie zdefiniuj metodę, w której jeden z parametrów wejściowych jest typu interfejsu. 2. Wywołaj metody interfejsu. 3. Przekaż do metody dowolny obiekt obsługujący interfejs (rysunek 8.24). Wskazówka  Przed przekazaniem obiektu do metody należy się upewnić, czy obiekt rzeczywiście obsługuje interfejs (więcej informacji na ten temat znalazło się w podrozdziale „Rozpoznawanie interfejsu” we wcześniejszej części tego rozdziału). W y k o r z y s t a n i e i n t e r f e j s ó w 271 Rozdział 8. Interfejs będący pochodną innego interfejsu Jeżeli inni programiści wykorzystują nasz obiekt poprzez określony interfejs, a niezbędne okaże się ulepszenie interfejsu, wówczas najlepiej pozostawić definicję oryginalnego interfejsu bez zmian. W języku C# istnieje mechanizm umożliwiający rozszerzanie interfejsu bez dodawania metod do interfejsu oryginalnego. Działanie tego mechanizmu polega na tworzeniu interfejsów pochodnych. Aby utworzyć interfejs będący pochodną innego interfejsu: 1. Zakładając, że wcześniej zdefiniowałeś jeden interfejs, zdefiniuj drugi. 2. Za nazwą interfejsu wpisz dwukropek, następnie 0COG1H(KTUV+PVGTHCEG, gdzie 0COG1H(KTUV+PVGTHCEG jest nazwą interfejsu, który chcesz rozszerzyć. 3. Oba interfejsy: oryginalny i rozszerzony możesz zaimplementować w ramach tej samej klasy (rysunek 8.25). Rysunek 8.25. Interfejs IPresident stanowi rozszerzenie interfejsu IParent. Oznacza to, że przy implementacji interfejsu IPresident należy zaimplementować nie tylko metody interfejsu IPresident, ale także metody interfejsu IParent KPVGTHCEG+2CTGPV ] XQKF5GPF-KFU6Q2NC[  _ KPVGTHCEG+2TGUKFGPV+2CTGPV ] XQKF KURCVEJ#TO[  _ ENCUU)GQTIG+2TGUKFGPV ] implementacja metod dla obu interfejsów Iparent oraz IPresident RWDNKEXQKF5GPF-KFU6Q2NC[ ] _ RWDNKEXQKF KURCVEJ#TO[ ] _ _ u s j e f r e t n i o g e n n i ą n d o h c o p s j e f r e t n I 272 Interfejsy Wskazówki  Definicje klas zaprezentowanych na rysunku 8.26 są sobie równoważne. Zaimplementowanie interfejsu oryginalnego i pochodnego jest tym samym, co zaimplementowanie tylko interfejsu pochodnego. W obu przypadkach uzyskuje się klasę zgodną z obydwoma interfejsami.  Definicje klas przedstawionych na rysunku 8.27 nie są sobie równoważne. Chociaż interfejs +)KXKPI2GTUQP jest kombinacją interfejsów: +2GTUQP oraz +5GPFU)KHVU, to zaimplementowanie interfejsu +)KXKPI2GTUQP nie jest tym samym, co oddzielne zaimplementowanie interfejsów +2GTUQP i +5GPFU)KHVH. Interfejs +)KXKPI2GTUQP może zawierać inne metody niż kombinacja metod interfejsów: +2GTUQP oraz +5GPFU)KHVU. I n t e r f e j s p o c h o d n ą i n n e g o i n t e r f e j s u Rysunek 8.26. Zaimplementowanie obu interfejsów: nadrzędnego i pochodnego jest tym samym, co zaimplementowanie tylko interfejsu pochodnego, ponieważ interfejs pochodny zawiera wszystkie składowe interfejsu nadrzędnego KPVGTHCEG+2CTGPV ] XQKF5GPF-KFU6Q2NC[  _ KPVGTHCEG+2TGUKFGPV+2CTGPV ] XQKF KURCVEJ#TO[  _ ENCUU)GQTIG+2TGUKFGPV ] implementacja metod dla obu interfejsów: Iparent oraz IPresident RWDNKEXQKF5GPF-KFU6Q2NC[ ] _ RWDNKEXQKF KURCVEJ#TO[ ] _ _ Rysunek 8.27. Mimo że klasa Telemarketer implementuje zarówno interfejs IPerson, jak ISendGifts, klasa ta nie jest zgodna z interfejsem IGivingPerson KPVGTHCEG+)KXKPI2GTUQP+2GTUQP +5GPFU)KHVU ] _ ENCUU)TCPFOC+)KXKPI2GTUQP ] _ ENCUU6GNGOCTMGVGT+2GTUQP+5GPFU)KHVU ] _ 273 Rozdział 8. Refaktoryzacja Refaktoryzacja (ang. refactoring) to mechanizm wykorzystywany w programowaniu obiektowym do działań z klasami i interfejsami. Polega on na tym, że jeśli dwie klasy spełniające podobne funkcje mają wspólny kod, wówczas ze wspólnego kodu tworzy się klasę bazową, a następnie, na podstawie tej klasy bazowej, tworzy się podklasy. Podklasy zawierają tylko ten kod, który je od siebie odróżnia1. Aby dokonać refaktoryzacji klas z wykorzystaniem interfejsów: 1. Jeżeli kilka klas implementuje ten sam interfejs w podobny sposób (kod implementacyjny jest identyczny dla wszystkich klas), utwórz klasę bazową. 2. Zaimplementuj interfejs w klasie bazowej. 3. Wprowadź w klasie bazowej kod implementacyjny dla każdej metody interfejsu. 4. Utwórz klasy pochodne na podstawie klasy bazowej. 5. Teraz możesz wykorzystać klasy pochodne poprzez interfejs (rysunek 8.28). Wskazówki  Jeżeli klasa bazowa implementuje interfejs, klasy pochodne są także zgodne z interfejsem.  W czasie projektowania klas, najpierw należy zdefiniować interfejsy, później utworzyć klasę bazową implementującą te interfejsy, a następnie utworzyć podklasy dziedziczące cechy klasy bazowej. Klasy pochodne wykorzystuje się poprzez interfejs. Właśnie taki mechanizm często wykorzystują doświadczeni programiści podczas pisania aplikacji. a j c a z y r o t k a f e R Rysunek 8.28. Obiektu Checking można użyć poprzez interfejs IAccount, ponieważ klasa Checking jest pochodną klasy AccountImpl, a klasa AccountImpl implementuje interfejs
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

C# i ASP.NET. Szybki start
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: