Java: nauka programowania dla początkujących  
 8391737519, 9788391737514 [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

NAUKA PROGRAMOWANIA DLAPOCZĄTKUJĄCYCH

.

Krzysztof Walczak

NAUKA PROGRAMOWANIA

DLA POCZĄTKUJĄCYCH

Wydawnictwo W & W

@ Copyright by Krzysztof Walczak Warszawa 2002

"JAVA Nauka programowania dla Autor: Krzysztof Walczak E-mail: [email protected]

początkujących"

www.ii.pw.edu.pl/-kwl

Książka

zawiera podstawowy kurs programowania w języku Java dla osób całkiem początkujących. Wykład został poprowadzony w sposób jak najbardziej czytelny i przejrzysty, a zamieszczone programy są dokładnie skomentowane i omówione. Książka jest przeznaczona dla szerokiego kręgu osób zainteresowanych programowaniem. Może być także wykorzystywana przez studentów wyż­ szych uczelni jako podręcznik do nauki programowania w języku Java. Na stronie www.ii.pw . edu. plrkwl są dostępne wersje źródłowe pro­ gramów omawianych w książce.

Wydanie I

Wydawca

Wydawnictwo W & W

Adres kor:spondencyjny: ~ __. --;;,- .

ul. Tołstoja 1/13 -: ~ :.:-i~( 01-910 Warszawa ./ \ , ::---..... . ' ~/ )~... \ tel. 0-504 213 450

l:

~

.

*/ ",\ i.1;., Nr ewid. ... ..A.q..5.5.. . . ... ...li~

Druk .~ A-Z DRUK '~'OY'y II/t ,~'.o:f:" -:/ Raszyn, ul. Słowikowskiego 21~i Zar"''';ld7 a'' i~ tel.(O-22) 720-35-61 ISBN 83-917375-1-9

Spis

treści

1

WSTĘP

7

2

WPROWADZENIE DO PROGRAMOWANIA

9

3

ŚRODOWISKO PRACY

13

4

KLASY, OBIEKTY, METODY

15

5 WPROWADZENIE DO

JĘZYKA

JAVA

5.1 Program w języku Java . 5.2 Typy danych . . . . . . 5.2.1 Typy całkowite 5.2.2 Typy rzeczywiste 5.2.3 Typ boolean . 5.2.4 Typ char . . . . 5.3 Operacja przypisania . 5.4 W yrażenia i operatory 5.4.1 Wyrażenia .. . 5.4.2 Operatory arytmetyczne 5.4.3 Operatory relacyjne. . . 5.4.4 Operatory logiczne ... 5.4.5 Bitowe operatory logiczne 5.4.6 Operatory zwiększania i zmniejszania . 5.4.7 Wieloznakowe operatory przypisania 5.4.8 Operator przecinkowy . . . . . . . . .

29

29

34

35

35

36

37

37

38

38

38

39

39

40

40

41

42

SPIS TREŚCI

4

5.4.9 Trójargume nto wy operato r? .. 5.4.10 Hierar chia i ł ączn o ść operatorów 5.5 Instrukcja z łożo na . . . . 5.5.1 Konwersja typ ów 5.6 Klasa String . . . . . . . . . . . . . . . 5.7 W prowadzanie i wyprowadzanie danych

. . . . .

42

43

43

44

47

51

6 PODEJMOWANIE DECYZJI W PROGRAMIE 6.1 Instrukcja if... else 6.2 Instrukcja switc h 6.3 Zad ani a . . . . .

55

55

59

60

7 ORGANIZACJA OBLICZEŃ CYKLICZNYCH 7.1 Instru kcj a while . . 7.2 Instrukcja do while 7.3 Instrukcja for . . . 7.4 Instru kcja break . . 7.5 Instrukcja continue 7.6 W ykorzystani e ety kiet w instrukcjach break i cont inue 7.7 Zadania . . . . . . . . . . . . . . . . . . . . . . . . . .

61

61

69

71

78

79

80

83

8 WYKORZYSTANIE TABLIC 8.1 Tablice w ję z yku J ava 8.2 P rzykł ad y 8.3 Zad an ia . . . . . . . .

85

85

114

147

9 PROJEKTOWANIE METOD 9.1 Wprowadzeni e . . . . .. . . 9.2 P rzekazywani e pa rametrów . 9.3 Prz e ci ąż ani e metod 9.4 P rzy k łady 9.5 Zad ania . . .

149

149

152

159

160

189

10 REKURENCJA 10.1 Wprowad zeni e.

191

191

SPIS TREŚCI 10.2 Algorytmy z powrotami 10.3 Sortowanie tablic 10.4 Zadania . . . . . . . . .

5 195

213

229

11 UZUPEŁNIENIE WIADOMOŚCI O KLASACH 11.1 Przykładowa klasa 11.2 Kontrola dostępu . . 11.3 Składowe statyczne . 11.4 Słowo kluczowe this . 11.5 Metoda toStringf) . . 11.6 Klasa do obsługi liczb wymiernych

231

231

238

241

243

244

246

12 KOMPOZYCJA

255

13 DZIEDZICZENIE 13.1 Wprowadzenie. 13.2 Klasa Obj ect . 13.3 Słowo kluczowe super. 13.4 Wywoływanie konstruktorów. 13.5 Przesłanianie metod i pól 13.6 Klasyabstrakcyjne . . . . 13.7 Polimorfizm . . . . . . . . 13.8 Kla sy i metody ostateczne

259

259

269

270

271

271

277

281

286

14 PRZECHOWYWANIE OBIEKTÓW W LIŚCIE 14.1 Zadania . . . . . . . . . . . . . . . . . . . . . . . .

287

309

15 INTERFEJSY

311

16 PAKIETY

325

WYJĄTKI

330

18 STRUMIENIE

342

19 APLETY

354

17

6

SPIS TREŚCI

20 ELEMENTY PRACY Z WYKORZYSTANIEM BIBLIO­ TEKI SWING 358

20.1 Umieszczanie komponentów . 359

20.2 Aplet jako aplikacja. . . . . . 363

20.3 Rozmieszczani e komponentów 366

20.4 Obsługa zdarz eń 371

20.5 Pr zykł ad y wykorz ystani a klas biblioteki Swing . 380

21 TESTOWANIE I URUCHAMIANIE PROGRAMÓW 21.1 Wprowadz enie. . . . . . 21.2 Testowanie programu . . 21.3 Uruchamianie programu

389

389

396

398

A WSKAZÓWKI DO WYBRANYCH ZADAŃ

400

Rozdział

1

WSTĘP Języka

Java nie potrzeba już nikomu rekomendować. Jest to język umoż­ liwiający pisanie programów, które mogą być uruchamiane na wszystkich platformach systemowych. Środowisko Javy zawiera bardzo bogaty zbiór standardowych bibliotek i narzędzi umożliwiających programowanie gra­ ficznych interfejsów użytkownika. Ponadto Java zapewnia bardzo wysoki poziom bezpieczeństwa uruchamianych programów. Język Java na pewno warto znać i umieć wykorzystać. Zachodzi tylko pytanie, czy nadaje się on do początkowej nauki programowania. Odpo­ wiedź jest prosta. Oczywiście tak, pod warunkiem, że nie będziemy się uczyć wszystkiego na raz. Najpierw wykład podstaw języka, a później stopniowo coraz to bardziej złożone zagadnienia. Niniejsza książka zawiera podstawowy kurs programowania dla osób całkiem początkujących, które nie zetknęły się z żadnym językiem pro­ gramowania. Nie jest to suchy opis języka, ale wykład programowania, w którym pierwszorzędne znaczenie ma zaprojektowanie właściwego al­ gorytmu i wybór prawidłowych struktur danych, a dopiero w drugiej kolejności są wykładane wszystkie niezbędne szczegóły języka. W książce znajduje się wiele przykładowych programów dokładnie wyjaśnionych i omówionych. Trudniejsze algorytmy są zapisywane naj­ pierw w pseudo-kodzie, a więc notacji, w której oprócz ściśle określonych struktur języka dopuszcza się używanie zdań języka naturalnego. Cały materiał został wyłożony w sposób jak najbardziej czytelny i przejrzysty, a zamieszczone programy są bogato skomentowane i opisane. Na ko ńcu większości rozdziałów znajdują się przykładowe zadania utrwa­ lające wyłożony materiał. Do części tych zadań w dodatku są podane

8

1.

WSTĘP

wskazówki lub kompletne rozwiązania. W książce nie są opisane szczegóły języka Java zbędne, zdaniem au­ tora, przy początkowej nauce programowania takie jak identyfikacja typu w czasie wykonania, klasy anonimowe, wielowątkowość, czy też prze­ twarzanie rozproszone. Wykorzystanie bardzo bogatej biblioteki Swing, umożliwiającej projektowanie graficznego interfejsu użytkownika zostało zilustrowane tylko kilkoma przykładami. Z tego względu w spisie litera­ tury są umieszczone pozycje zawierające informacje uzupełniające. Nie są to jednak książki przeznaczone dla początkującego programisty. Warto zaznaczyć, że bardziej zaawansowany kurs programowania z uwypukleniem wykorzystania narzędzi pozwalających na wizualne pro­ jektowanie interfejsu użytkownika jest zawarty w następnej pracy [6] z cyklu książek o języku Java wydanych przez Wydawnictwo W & W. Książka jest przeznaczona dla szerokiego kręgu osób zainteresowanych programowaniem. Może być także podręcznikiem do nauki programowa­ nia dla studentów wyższych uczelni.

Rozdział

2

WPROWADZENIE DO PROGRAMOWANIA Programowani e komputerów najogólniej m ówi ą c, polega na zapisaniu li­ sty pol e c eń do wykonania przez komputer w pewnym umownym języku . Taką listę poleceń nazywam y pr ogram em. P rogram jest to za tem t ekst zapisany w symbo lice ob owi ązuj ącej w danym j ęz yku programowania , który jest zro zumi ały przez komputer. Obecnie podamy kolejn e fazy procesu r o zwi ąz ywani a problemów za pomo c ą komputera. S ą one n as tępuj ąc e : • sfor mu łowan i e problemu (spe cyfikacja) , • ana liza problemu i zn al ezienie metody jego rytmu,

rozwi ąz ani a

tzn. algo­

• zakodowanie algoryt mu (napisanie programu), • uruchomienie i przet estowanie pr ogramu, • konserwacja programu. Naj ważn iej sz ą fazą jest pr zeprowad zeni e d okładn ej analizy problemu, który n al eży rozwiązać. Analiza t a powinna doprow adzić do zdefinio­ wania sposobu ro związani a zadania tzn . algorytmu. Algor ytm jest to metod a r ozwi ązania pewnego zagadnienia s fo rmu łowan a w skoń czon ej liczbie kroków element arn ych. Warto zazna czyć, że definicja kroku ele­ mentarnego zal e ży od stopnia szcze gółowości, na jakim jest rozpatrywany dany algorytm.

10

2. WPROWADZENIE DO PROGRAMOWANIA

Podczas projektowania algorytmów powinno się stosować systema­ tyczne techniki ich projektowania. Do podstawowych technik należą pro­ jektowanie wstępujące i zstępujące. Projektowanie wstępujące polega na wyodrębnieniu w danym algoryt­ mie niepodzielnych części , które następnie łączy się w większe jednostki tak długo, aż otrzymamy rozwiązanie danego problemu. Projektowanie to można określić jako projektowanie od szczegółu do ogółu. Natomiast pro­ jektowanie zstępujące polega na zaprojektowaniu algorytmu w pierwszym etapie bez rozpatrywania szczegółów. Częściami składowymi algorytmu są bloki funkcjonalne realizujące ściśle określone operacje. Następnie w dalszej fazie projektowania uściśla się je tak długo, aż dojdzie się do operacji, które można zaprojektować bezpośrednio. Projektowanie zstę­ pujące określamy jako projektowanie od ogółu do szczegółu. W praktyce przy tworzeniu wielu algorytmów stosuje się metodę mie­ szaną, w której wykorzystuje się obie wspomniane techniki projektowa­ nia. Można jednak stwierdzić, że przy projektowaniu nowych algorytmów częściej stosuje się technikę zstępującą, a przy dopasowywaniu istnieją­ cego algorytmu do zmienionych założeń częściej używa się techniki wstę­ pującej .

W niniejszej książce będziemy wykorzystywać obie wymienione tech­ niki projektowania algorytmów. Mamy nadzieję, że Czytelnik bez trudu zorientuje się, która technika została zastosowana w konkretnym przy­ padku. Równolegle z opracowaniem algorytmu należy wybrać odpowiednią strukturę danych. Struktura danych określa sposób przechowywania da­ nych wykorzystywanych przez program . Często mówi się nawet, że pro­ gram jest to algorytm plus struktura danych. Program w postaci ciągu instrukcji języka nazywa się programem źró­ dłowym i jest przechowywany w plikach z rozszerzeniem .java. Kompi­ lator tłumaczy program źródłowy na kod bajtowy (przechowywany w plikach z rozszerzeniem .class), który jest interpretowany przez JVM (Java Virtual Machine - Wirtualna Maszyna Javy). JVM jest zainstalo­ wana na danej platformie systemowej lub wchodzi w skład przeglądarki WW\V. Taka strategia pozwala na uzyskanie przenośności pomiędzy róż­ nymi platformami. Na każdej z nich musi tylko istnieć Wirtualna Ma­ szyna Javy interpretująca kod bajtowy. Wirtualne Maszyny Javy mogą różnić się między sobą różnymi szczegółami, ale każda z nich interpretuje ten sam kod bajtowy, który będzie działał tak samo. Trzeba podkreślić,

2. WPROWADZENIE DO PROGRAMOWANIA że

11

pod tym względem Java różni si ę od wi ększości j ęzyków pr ogr amowania, gdzie kompilator produkuj e kod binarny bezpośrednio wykonywaln y (wymaga to istnienia różnych kompilatorów na różne platformy, a co więc ej nie mo żn a wtedy zapewnić przenośności). Kolejną fazą po utworzeniu programu jest jego uruchomienie , przetestowanie i usuni ęci e błędów . Uruchamianiem nazywamy pro ces zmierzający do zlokalizowania przyczyn i usunięcia znanych błędów. Natomiast testowanie jes t to badanie programu w celu stwierdzenia, czy są s pe ł n i o n e określ on e kryteria, np . czy pro gram zachowuje się poprawnie w r óżny ch sytuacj ach w przypadku uruchamiania na różnych danych. W szczególności celem testowania może być znalezienie bł ędów, które zakr adł y się do programu. Błędy stwierdzone podczas testowania trzeba następnie znaleźć i poprawi ć , a testowanie prowadzić dal ej. Tak więc uruchamiani e i testowani e prz eplat aj ą się i uzupełniają. Kompilator m oże sam wykryć niektóre błędy popełnione prz ez programistę. Bł ędy t e można porównać do bł ędów ortograficznych i s k ł a­ dniowych j ęzyk a naturalnego. Nazyw a się je błędami kompilacji. Inny rodzaj błęd ów t o błędy wykonania. Uaktywniają się one podczas wykonywania programu wt edy, gdy komputer nie może zrealizować wymagan ej operacji. Przykładem takiego błędu jest próba podzielenia pr zez li czb ę O. Osobną kat e gori ą bł ędów , które muszą by ć wykr yte przez programistę, są błędy logiczne. Te błędy sprawiają , że pro gram działa ni eprawidłowo np. podaje niep oprawn e wyniki, mimo i ż nie jest sygnalizowany ż ad en błąd. Błędy logiczne w ynikają najczęściej z pomył ek popełniony ch w fazie projektowani a algorytmu . Są to błędy, kt óre mo gą być często bardzo trudne do wykrycia i poprawienia. Gotowy, uruchomiony i przetestowany pro gram wymaga następnie konserwacji. Kon serwacja programu jest konieczna ze względu na potrz ebę poprawiania nie wykrytych podczas testowania błędów lub realizowania wymaganych przez użytkownika zmian i roz sz erz eń . Konserwacja oprogramowania jest procesem długotrw ał ym , dlatego wprowadzanie zmian nie może być zbyt pracochłonne . W celu rozwiązania problemu za pom o c ą komputera nal eży prz ede wszystkim ułoży ć algory t m. Określając najpro ś ci ej , algorytm jest to metoda rozwiązania danego problemu. Aby rozwiąza ć jakiś problem, nal eży wykonywać kolejno pewne cz y n n oś c i, które w algoryt mie są nazywane krokiem. Poszczególnym krokiem algorytmu może być element arn a operacja (bardzo prosta) lub op eracja złożona (bard ziej skomplikowan a) .

12

2. WPROWADZENIE DO PROGRAMOWANIA

Istotną cechą każdego algorytmu powinna być ogólność, co oznacza, algorytm nie może podawać metody rozwiązania pojedynczego problemu lecz całej klasy problemów podobnych. Na przykład, można podać algorytm znajdowania liczby maksymalnej w ciągu liczb, ale nie w jednym konkretnym ciągu a we wszystkich ciągach spełniających określone warunki. Algorytmy można zapisywać na wiele sposobów. Można je przedstawiać przy pomocy języka naturalnego jak również b ezpośrednio przy pomocy języka programowania. Często do zapisu algorytmu stosuje się technikę pośrednią między językiem naturalnym a językiem programowania tj. przy pomocy pseudo-kodu . Ps eudo-kod jest to narzędzie czę­ ściowo sformalizowane, w którym do opisu różnych czynności obok pewnych ustalonych struktur można używać języka naturalnego. W niniejszej książce przyjmiemy, że tymi ustalonymi strukturami będą instrukcje sterujące języka Java zapisywane w sposób nieformalny z wykorzystaniem języka naturalnego. W pseudo-kodzie będziemy podawać jedynie bardziej złożone algorytmy. Pierwszy algorytm zapisany w pseudo-kodzie znajduje się w rozdziale 7, a następne pojawiają się wielokrotnie na kolejnych stronach tej książki. że

Rozdział

3

.

SRODOWISKO PRACY Do uruchomienia programu napisanego w języku Java potrzebny jest kompilator, Wirtualna Masz yn a Javy no i oczywiście wszystki e niezbędne biblioteki. Wszystkich tych narzędzi dostarcza dla języka Java 2 środowi­ sko uruchomieniowe Java 2 SDK (Software Develop er Kit) . Środowisko to można b ezpłatnie przekopiować ze strony: java.sun.com W tym należy wykonać nast ępujące czynności: 1. Wybrać opcję Downloads ( z lewej strony ekranu).

2. Z kolejnego ekranu dard Edition.

wybrać opcję

3. Z następnego ekranu 1.4.0.

Java TM 2 Platform, Stan-

wybrać najnowszą wersję środowiska np.:

J2SE

4. Z kolejnego ekranu wybrać system operacyjny, w którym chcemy działać np . Windows . 5.

Wybrać

SDK i ściągnięty plik z rozszerzeniem .exe dowolnym katalogu.

umieścić

w

6. Z tego samego ekranu można przekopiować dokumentację środowi­ ska wybierając (nieco niżej) opcję J2SE v1.4 Documentation. Po przekopiowaniu pliku j2sdk-L4_0_02-windows-j586. exe trzeba na własnym komputerze wykonać jesz cze dwie czynności :

3. ŚRODOWISKO PRACY

14 1.

Wykona ć

plik j2sdk-L4-_0_02-windows-j586. exe, co spowoduje utworzeni e katalogu j2sdk1.4.0_01, w którym będzie umieszczone śro­ dowisko SDK.

2. Ustawić ścieżkę do stępu do katalogu j2sdk1.4.0_01/bin (zmienna systemowa Ph. TH) . Aby skompilować program kompilator pisząc:

źródłowy

trzeba z linii

poleceń wywoł ać

j avac Abc . j ava

gdzie Abc jest nazwą pliku (z roz szerz eni em .java). Jeżeli

kompilacja zakończy się pomyślnie, zostaną utworzone pliki zawierające kod bajtowy z ro zszerzeniem .class. Wirtualną Maszynę

Javy

wywołujemy następująco:

java Abc Zwró ćmy uwagę, ż e

matycznie

zostaną

w tym przypadku nie podajemy rozszerzenia (autowykorzystane pliki z rozs zerzeniem .class).

W systemie Windows polecenia możemy wydawać, uruchamiając program command.com , przechodząc do op cji Wiersz polecenia (z menu Start poprzez wybór op cji Programy/Akcesoria) lub też na przykład wykorzystując sys tem Norton Commander. Można wtedy utworzyć plik wsadowy z rozszerzeniem .bat. Na przykład, plik o nazwie c.bat może mieć zawartość:

j avac Abc. j ava Wykonanie pliku c. bat powoduj e skompilowanie pliku Abc.java oczywiście pod warunkiem , że j est ustawiona ści eżka dostępu do katalogu

j2sdk1.4.0_01/bin. VV celu uruchomienia Wirtualnej Maszyny Javy cl .bat o zawartości :

można utworzyć

plik

java Abc Warto jeszcze wiedzieć, że s ą różne systemy ułatwiające kompilację i wykonanie programów napisanych w języku Java. Jednym z takich systemów jest Kawa, w którym możemy edytować program i od razu go kompilować , a następnie wykonywać. Różne możliwoś ci pracy zawarte są w dość oczywistych opcjach menu i dlatego nie będziemy ich opisywać.

Rozdział

4

KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy za wyjątkiem zmiennych prostych są obiektami. Sam pro gram t eż jest obiektem pewn ej klasy. Aby utworzyć obiekt należy najpierw zdefiniować klasę, która jest wzorem do tworzenia obiektów tej klasy. Klasa definiuj e zarówno dane jak i algorytmy służące do ich prz etwarzania. Dane są zapisywane w klasie w postaci pól (zmiennych lub stałych składowych), a algorytmy w postaci metod. Metodą jest wydzielony fragment programu , na ogół zawierający parametry, który może operować na ściśle określonych danych. Aby utworzyć klasę, należy użyć słowa kluczowego class wykorzystując poniższy schemat (tekst następujący w wierszu po dwóch znakach / / jest komentarzem): opisujące dane,

class nazwaKlasy {

II deklaracja pól typ zmiennaPierwsza; typ zmiennaDruga; II deklaracja metod typ metodaPierwsza(pararnetry)

4. KLASY, OBIEKTY, METODY

16 {

II

ciało

metody

}

typ metodaDrugaCparametry) {

II

ciało

metody

} } przykładu rozważmy klasę pozwalającą tworzyć obiekty zawieinformacje o paczkach, które na przykład trzeba przewieź ć cięża­ rówką. Paczek jest więcej niż może pomieścić ciężarówka i chodzi o to, by załadować na cię żarówkę jak najwięcej paczek tak, aby suma wartości tych paczek była maksymalna. Dla każdej paczki musimy zatem dysponować następującymi danymi: długość podstawy, szerokość podstawy, wysokość i oczywiście wartość paczki. Pierwsza wersja klasy Paczka (bez proj ektowania metod) może wyglą­ dać następująco (typ int jest typem całkowitym omówionym w rozdziale 5):

Dla

rające

class Paczka { int int int int

dlugosc; szerokosc; wysokosc; wartosc;

}

Obiekt klasy Paczka możemy utworzyć w dwóch etapach. Najpierw trzeba zadeklarować referencję do obiektu klasy Paczka: Paczka telewizor; Referencja czyli inaczej odnośnik identyfikuje dany obiekt. Możemy sobie wyobrazić, że referencja podaje między innymi adres w pamięci, gdzie jest umieszczony obiekt, jego wielkość itp. Po wykonaniu powyższej instrukcji zmienna telewizor posiada wartość nul.L, czyli nie zawiera referencji do żadnego obiektu. Aby utworzyć nowy obiekt, należy wykorzystać op erator new:

4. KLASY, OBIEKTY, METODY telewizor

17

= new Paczka();

Operato r n e w tworzy nowy ob iekt klasy Paczka, a referencja do niego jest przypisywana zm ien nej telewi zor (przy po mocy operatora = ). Od tego mom entu zm ienna telewizor nie posiada ju ż w ar t o ś ci null , lecz odnosi s ię do pewnego obiekt u klasy Paczka. Obie p owyż sz e instrukcje m o żn a po łączyć i u tworzy ć ob iekt klasy Paczka w jednym etapie: Paczka telewizor

= new Paczka() ;

Każd y

obie kt pos iada w łasną ko p i ę pól zade kla rowanych w klasie. D o st ęp do tych pó l m o żn a uzy skać przy pomocy operatora" ." . (kropka) . Ustawienie wartośc i wszystkich pól dla obiekt u, do którego referencją jest zmienna telew izor wygl ąd a n as t ę puj ąc o : telewizor .dlugosc = 150; telewizor.szerokosc = 80; telewizor .wysokos~ = 120; telewizor .wartosc = 6000 ; Ob iektów danej klasy m o żn a u two rzy ć dowolnie utworzymy jes zcze jeden obiekt klasy Paczka: Paczka pralka

duż o .

przy k ład u

Dla

= new Paczka();

Wart o śc i

pól ob iekt u, do kt órego refere ncją jest zmienna pralka, ustawiam y analogicznie j ak pop rzed nio: pralka .dlugosc = 70; pralka .szerokosc = 50; pralka .wysokosc = 130 ; pralka.wartosc = 5000; Jeszcze raz po d k reś l my, że każ d y obiekt klasy P aczka ma s woją wł a­ pól zdefiniowanych w klasie. Ilustruje t o rys. 4.1. Ob liczenie objętośc i paczki - obiekt u, do którego referen cj ąj es t zmienna telewizor można dokonać przy pomocy/ instrukcj i: . sną kopi ę

/

obj = telewizor. dlugosc * telewizor . wysokosc;

*

5

tel,ew izor. s ~erokosF15 ~; I II . . . ./1 ...

,-

.~

-~v\t :"'/

. '

- - - - ...

_---t

r

/

.~

....

18

4. KLASY, OBIEKTY, METODY

telewizor

pralka

dlugosc 150 szerokosc 80 wysokosc 120 wartosc 6000

dlugosc 70 50 szerokosc 130 wysokosc 5000 wartosc

Rysunek 4.1: Obiekty klasy Paczka, do których referencjami telewizor i pralka



Każde

pole i metoda zdefiniowane w klasie może mieć wyszczególniony specyfikator dostępu określany przez słowa: public, private oraz protected. Umieszczenie słowa public oznacza, że dany składnik jest dostępny w całym programie. Słowo private oznacza, że dany składnik może być wykorzystywany tylko przez metody danej klasy. Specyfikator dostępu określony przez słowo protected jest omówiony w rozdziale 13 i na razie nie będziemy się nim zajmować. Istnieje jeszcze specyfikator domyślny występujący wtedy, gdy nie używamy żadnego słowa (pola zdefiniowane w dotychczasowej wersji klasy Paczka miały właśnie domyślny specyfikator dostępu) . Domyślny specyfikator ma znaczenie takie samo jak specyfikator public dla klas zdefiniowanych w tym samym pakiecie. Ponieważ pakietami zajmiemy się dopiero w rozdziale 16, na razie przyjmiemy, że specyfikator domyślny jest równoważny specyfikatorowi public. Zmieńmy teraz definicję klasy Paczka w sposób następujący:

class Paczka { private private private private

int int int int

dlugosc; szerokosc; wysokosc; wartosc;

}

W tym przypadku nie ma już instrukcji rodzaju:

możliwości wykorzystywania

telewizor.dlugosc = 150;

w programie

4. KLASY, OBIEKTY, METODY

19

czy też

obj = telewizor.dlugosc * telewizor.wysokosc;

*

telewizor.szerokosc

Pola dlugosc, szerokoec, wysokosc i wartosc są niedostępne na zeklasy. I tak w większości przypadków powinno być . Dostęp do tych pól czy też wykonywanie na nich operacji powinno odbywać się przy pomocy metod . Ogólny schemat dla utworzenia metody jest następujący: wnątrz

typ nazwa(parametry) {

II

ciało

metody

}

Dla

przykładu

tości

utwórzmy teraz

metodę pozwalającą

na obliczenie

obję­

paczki.

public int DbliczDbj() {

return dlugosc

*

szerokosc

*

wysokosc;

}

Metoda ta powinna

być

umieszczona

wewnątrz

definicji klasy Paczka:

class Paczka { private private private private

int int int int

dlugosc; szerokosc; wysokosc; wartosc;

public int DbliczDbj() {

return dlugosc

*

szerokosc

*

wysokosc;

} }

Metoda ObliczObj () nie zawiera żadnych parametrów i działa na polach zdefiniowanych w klasie Paczka. Mimo że są to pola ze specyfikatorem

4. KLASY, OBIEKTY , METODY

20

private metoda ob liczO bj O ma oczyw ise rę do nich d o st ęp , po n i eważ sama j est skł ad nikie m klasy P aczka. Zw róć my uwagę na s łowo kluczowe return o z naczające pow rót do instrukcji , w kt órej dan a meto da z ostała wywołan a wraz z po daniem obliczonej wartośc i do naz wy funkcji . Obecnie zajmiemy s i ę szczegó lną meto dę zwa ną konst ruk t orem . Konstru kt or jest wy wo ływany zawsz e w mom encie tworz enia ob iekt u . J e żeli konstruktor nie zosta ł zde finiowany, t o wt edy jest wywoływany kons trukt or d omy ślny - bezpara metrowy p rzyp is ując y wszystkim p olom wa rtość O. J eż eli w klasie jest zd efiniowan y konstruktor z param etrami, to wt edy konstrukt or d o myślny nie j est tworzony auto matycznie. W razie konieczności wykorzystywania konstruk t ora bez param etrów trzeba go jawnie zdefi ni ować .

Kon struk t or ma zawsz e n az wę definicji nie woln o podać typu. Na dla klasy P aczka :

taką s amą pr z ykład,

jak nazwa klasy i w jego zaproj ektuj my konstrukt or

public Paczka(int aDl,int aSzer ,int aWys,int aWart) {

dlugosc = aDl; szerokosc = aSzer; wysokosc = aWys; wartosc = aWart; }

Konstrukt or t en ma cztery para met ry, nazywan e c zęsto parametram i formalnymi , któ rych wart o ś ci s łużą do pr zypi san ia wartośc i po lom obiektu. Tak j ak dl a innych metod d efinicję konstrukt or a umi eszczamy wew nąt rz definicji klasy :

class Paczka { private private private private

int int int int

dlugosc; szerokosc; wysokosc; wartosc ;

public Paczka(int aDl ,int aSzer ,int aWys ,int aWart) {

dlugosc = aDl;

4. KLASY, OBIEKTY, METODY

21

szerokosc = aSzer; wysokosc = aWys; wartosc = aWart; }

public int ObliczObj() {

*

return dlugosc

szerokosc

*

wysokosc;

} }

Obiekty klasy Paczka Paczka telewizor

m ożemy

te ra z

tworzy ć

przy pom ocy instrukcji:

= new Paczka(150,80,120,6000);

Utworzony obiekt klasy Paczka, do kt órego r efer en cją jest zmienna telewizor , ma swój zestaw pól o przypisanych w a r t ości ach 150,80,120,6000. Zwró ćmy uwagę, ż e parametry podane w momencie wywołania metody w tym przypadku konstruktora, są nazywan e param etrami aktualnymi. Trzeba zapam ię t ać, że w języku Java par am etry są przekazywane zawsze przez warto ść, co oznacza, ż e wartoś ć parametru aktualnego jest przekazywana do parametru formalnego. Ozn acza to, ż e nie ma możli­ woś ci zmiany parametru aktualnego poprzez wykon ani e metody. Do tego zagadnienia powrócim y jeszcze w nast ępny ch rozd zi ał ach , a teraz zastanówmy s ię , j ak o b l i czyć obj ętość paczki - obiektu , do kt órego r efer en cj ę zawiera zmi enna telewizor. Otóż wystarczy w tym celu wywoł ać met od ę obli ceObjf] dla odpowiedniego obiektu klasy Paczka , wykorzystuj ąc opera tor kropki . Ilus truje to poni ższa ins trukcja: int objl

= telewizor.ObliczObj();

Met ody z danej klasy czyli w naszym przypadku klasy P aczka m o gą być dla obiektów tej klasy. A zatem na pr zykład, jeżeli obiekt o nazwie inny jest obiektem inn ej klasy niż Paczka, to poniższa instrukcja sp owoduje błąd kompilacji: wywoł ywan e wył ąc znie

int objl

= innny.ObliczObj() ;

II

BŁĄD

KOMPILACJI

Zasygnalizujmy jeszcze skąd metoda obliczObj Owie dl a jakiego obiektu , czyli na jakich w art ości ach , ma wykonać obli czeni a. Jak wiad omo , obiekt ów klasy Paczka może być dowolni e du żo i metod a obliczObjf)

4. KLASY, OBIEKTY, METODY

22 może obliczyć objętość każdego

z tych obiektów. W momencie wywoła­ nia metody obliczObj () jest do niej przekazywana referencja do obiektu, na rzecz którego nastąpiło wywołanie. W naszym przypadku referencją tą jest telewizor i dla tego obiektu nastąpią obliczenia. Referencję tę można do metody przekazać w sposób jawny przy pomocy słowa kluczo­ wego this, co wyjątkowo może być przydatne. Zostanie to omówione w dalszej części książki w rozdziale 11. Przeanalizujmy teraz ostatnią wersję definicji klasy Paczka. Ponieważ pola klasy są deklarowane ze specyfikatorem private, nie ma możliwości wykonywania na nich operacji na zewnątrz klasy. I bardzo dobrze. Do nadania wartości początkowych polom obiektu klasy Paczka służy kon­ struktor, a do obliczenia objętości metoda obliczObj(). Może być jednak potrzebne wyprowadzenie rozmiarów obiektu - paczki czy też jej warto­ ści. W tym celu można utworzyć metody deklarowane ze specyfikatorem public, co oznacza, że można je wykonać w całym programie. Jedna z tych metod ma postać: public int PodajDlugosc() {

return dlugosc; }

Zadaniem metody podajDlugosc() jest tylko zwrócenie wartości odpo­ wiedniego pola klasy. Można się teraz zastanowić, czy warto było pola klasy deklarować ze specyfikatorem private . Czy nie lepiej po prostu zezwolić na dostęp do nich w całym programie. Otóż na pewno warto. Dzięki temu przypi­ sanie wartości tym polom odbywa się wyłącznie w konstruktorze i przy szukaniu błędu w programie nie musimy sprawdzać, czy gdzieś w progra­ mie nie nastąpiła przypadkowa zmiana wartości któregoś z pól. Ponadto przykładowa metoda podajDlugosc() jest naj prostsza z możliwych i ła­ two można dokonać jej zmiany tak , by zwracała zmodyfikowaną wartość pola (na przykład można przeliczyć centymetry na metry) . Ostateczna wersja definicji klasy Paczka jest zatem następująca: class Paczka { private int dlugosc;

private int szerokosc;

4. KLASY, OBIEKTY, METODY

23

private int wysokosc; private int wartosc; public Paczka I irrt aDl, int aSzer, int aWys,int aWart) {

dlugosc = aDl; szerokosc = aSzer; wysokosc = aWys; wartosc = aWart; }

public int PodajDlugosc() {

return dlugosc ; }

public int PodajSzerokosc() {

return szerokosc; }

public int PodajWysokosc() {

return wysokosc; }

public int PodajWartosc() {

return wartosc; }

public int DbliczDbj() {

return dlugosc

*

szerokosc

}

public int

~bliczPodst()

{

return dlugosc

*

szerokosc;

*

wysokosc;

4. KLASY, OBIEKTY , METODY

24

} } Z auważmy , że

w definicji klasy Paczka dod ali śmy jeszcze m e t odę oblicz­ pole powierzchni pod st awy paczki , co mo ź e s ię przydać pr zy up akowywaniu paczek. Po ty m wstęp ie mo ż em y wreszcie po dać jak n api s ać pierwszy pr ogr am w język u J ava. P rog ram jest rów nież obiektem pewnej klasy, kt ór a musi by ć zdefiniowana ze sł owe m public. Koni eczni e t rzeba z ap ami ęt ać , że nazwa pliku , w kt ór ym jest umi eszczona t a klasa , musi by ć t aka sama jak nazwa klasy, u w z gl ędni aj ąc równi eż du ż e lit ery. Wykon ani e pr ogr amu rozpoczyn a si ę od metod y o nazwie main f) ty pu void (co oznacza, ż e nie zwraca ona żad nej wartoś c i) zadeklarowanej ze specy fikatora mi public i static. Specyfikator static zost anie d okładni e omówiony w roz dziale 11, a te raz musi nam w ystar cz yć inform acja, że s k ład n i k i zadeklarowane ze s łowe m static są związane z kl asą , a nie z poszczególnym i ob iektami klasy. J eż eli sk ład n i k jest zadeklarowany ze s łowe m static, to m o ż emy m i eć clo niego d ostę p bez utworzenia ż ad nego obiekt u tej klasy (pod a­ jemy n azwę klasy i po kropce n azwę skł adnika ). 'W szyst kie pola sta­ ty czne maj ą t aką samą war t ość dla wszystki ch utworzonych ob iektó w danej klasy. Ponadto metod y statyczne m ogą wykor zystywać wy łącz n ie sk ład ni k i statyczne (po la i met od y). MetocIa mai n j) posiada par am etry, które są t abli c ą ty pu String. Wy­ korzystanie tyc h parametrów omówimy bliż ej w rozdziale 9. Schemat , wedłu g którego m ożemy u tworzyć pr ogram , m oż e by ć na­

Pod st t)

p oz walającą ob lic zyć

st ępuj ąc y:

public class Pierwszy { public static void main(String[] args) {

new Pierwszy (); II utworzenie obiektu klasy Pierwszy }

-

public Pierwszy() {

II instrukcje

II konstruktor dla klasy Pierwszy

4. KLASY, OBIEKTY, METODY

25

} }

W metodzie main() tworzymy wyłącznie obiekt klasy Pierwszy. Obiekt ten jest naszym programem. W momencie tworzenia obiektu zawsze jest wywoływany konstruktor, który w tym przypadku istnieje i oczywiście ma nazwę Pierwszy(). Referencj i do obiektu klasy Pierwszy nie zapamię­ tujemy w żadnej zmiennej , po prostu nie jest to do niczego potrzebne. Natomiast wszystkie niezbędne instrukcje zapisujemy w konstruktorze. A oto nasz pierwszy program skonstruowany zgodnie z powyższym schematem:

Program 4.1 public class Pierwszy { public static void main(String[] args)

{

new Pierwszy () ;

}

public Pierwszy() {

Paczka telewizor; new Paczka(150,BO,120,6000); int objetoscl ; telewizor.ObliczObj(); System.out.println("Objętośćpaczki

o rozmiarach: II +

'\n' + telewizor. PodajDlugosc () + II , 11+ telewizor. PodajSzerokosc () + " , II + telewizor. PodajWysokosc () + ' \n' + "vynos i : II + '\n' + objetoscl); } }

Zadaniem tego prostego programu jest utworzenie obiektu klasy Paczka, obliczenie objętości tego obiektu i wyprowadzenie niezbędnej informacji. Zwróćmy uwagę, że do wyprowadzenia informacji można wykorzystać instrukcję

4. KLASY, OBIEKTY, METODY

26

System.out .println(par) ; gdzie param etr par m oż e być typu String (typ int jest automatycznie tran sfor mowan y do ty pu String). W ięcej informac ji o klasie String za­ wiera nas t ępny roz dz ia ł. Teraz z auważ my ty lko, ż e op erator + słu ży do ł ączenia obiektów klasy St rin g, a znak '\n' umożliwi a wyp rowadzenie zna ku nowej linii. Z auważmy jeszcze, że program w j ęz yku Java m oż n a zap roje ktować , wykorzys tuj ąc ty lko m e t od ę maint ) b ez konst ruk tor a klasy. Ilu st ruj e to p oni żs zy schemat: public class Drugi { public static void main(String[] args) {

II instrukcje } }

P rogram 4.2, skonst ruowany zgodnie z powy żs zym sche matem, wy­ konuj e analogiczne ope racje j ak progra m 4.1:

Program 4.2 public class Drugi { publi c static void main(String[] args) {

Paczka telewizor = new Paczka(150,SO,120,6000);

int objetosc1 = telewizor.obliczObj();

System.out.println("0bjętośćpaczki o rozmiarach: "); System .out.println(telewizor.PodajDlugoscO+ II , "+ telewizor. Podaj Szerokosc O + " , II + telewizor .PodajWysokosc() + '\n' + Il wynos i : " ) ; System.out.println(objetosc1);

} }

4. KLASY, OBIEKTY, METODY

27

Rozwiązan ie pierwsze będz i e my stosować częśc iej, po nieważ po pierw­ sze jasno st wierdza, że program jest też obiekt em, a po drugie um ożli­ wia wywoł ywani e w konstruk torze klasy metod , kt óre nie są statyczne. W metodzi e m ain f), która jest statyczna , m ożn a wy wo ływać ty lko me­ tody statyczne. Aby wy korzyst ać m et o dę , która nie jest statycz na, n al eży utworz yć obiekt d an ej klasy i dopi ero dla tego obiekt u wywo łać me t odę . Zostanie to d okładni ej zilust rowane w rozdziale 9. Nato miast rozwiązanie drugie można zast os ować do prz et est owani a klasy , kt ó r ą b ęd zi emy p ó ź­ niej wykorz ys t ywać w innych aplikacjach. N iezbęd ne inst ruk cje t estuj ąc e zamieszczamy wte dy w metodz ie maint ). Więcej przykł ad ów ilu s truj ący ch p racę z metod ami i pr zekazywanie parametrów zawiera rozdz ia ł 9, a obecn ie zwró cimy jeszcze uwagę na mo żliwość przypisywani a referencji. W yo br aźmy sobie, że mamy zade­ klarowane t rzy zmienne referencyjne do obiektów klasy P aczka : ref1 , ref2 , ref3. Można tego d ok on ać pr zy po mocy instrukcji:

Paczka ref1, ref2 , ref3; Jak już wiemy, w tej chwili zmienne te nie o d nosz ą się do żad nego obi ektu , a ich war t oś ć jest null . Utwórzmy te raz dwa ob iekty klasy Paczka, do kt órych referencj ę b ęd ą zaw ierały zmienne ref 1 i ref2 : ref1 ref2

= new

Paczka(50,50,10,100);

= new Paczka(100,100,40,500);

Zmienn a referencyjn a ref3 w dal szym c iąg u posiad a war tość null. W j ęzyku J ava m ożn a do konać n as t ępuj ąc ego przypisani a : ref3

= ref1;

Oznacza to, że zmienna ref3 zawiera r efer en cję do te go sa mego obi ektu, do którego o d n osi ł a si ę zmienn a ref1. Zmienn ej ref 3 moż na n as t ępni e p rzypis ać war t oś ć inn ej zmi enn ej referencyjn ej , co ilustruje p oniższa instrukcja. ref3

= ref2;

P rogram 4.3 ilustruj e rencji.

m ożliwości

st warzane prz ez pr zypisywani e refe­

4. KLASY, OBIEKTY, METODY

28

Program 4.3 public class Trzeci { public stat ic void main(String[] args) {

new Trzeci O;

}

public Trzeci O

{

Paczka refl, ref2, ref3;

II utworzenie dwóch obiektów klasy Paczka

refl new Paczka(50,50,10,100) ;

ref2 = new Paczka(100,100,40,500);

ref3 = refl;

System.out.println("Dbjętość

paczki o rozmiarach :

ref3.PodajDlugoscO+ II , "+

ref3.PodajSzerokoscO + ", I I +

ref3. PodajWysokosc O + l \n l + "wynosi: ref3.DbliczDbj());

ref3 = ref2;

II

II

+

II

+

+

System .out .println(1I0bjętość paczki o rozmiarach : ref3 .PodajDlugoscO+ II , 11+

ref3 . PodajSzerokosc O + ", II +

ref3. PodajWysokosc O + l \n l + "vynos i : II + ref3.DbliczDbj());

} }

I ostat nia już informacja w tym rozdzi ale. W języku J ava nie ma koni eczności dbania o usuwanie obiektów ju ż niepotrzebnych. System sam usunie wszystkie obiekty, do kt óry ch nie istnieje żadna referencja .

Rozdział

5

WPROWADZENIE DO JĘZYKA JAVA 5.1

Program w

języku

Java

W ję zyku Java program jest zestawem klas. Poza defini cjami klas mogą występować tylko dwi e deklaracje: package oraz import, które będą omówione w dalszej c zęś c i k siążki. Wszystkie klasy tworzące program mogą być zapisane w jednym lub w kilku plikach , których rozsz erzenie musi by ć .java. Dla uproszczenia przyjmiemy na razie, że je żeli klasy s ą umiesz czone w kilku plikach, to wszystkie pliki z n aj d ują się w jednym katalogu . Jeśli klasa nie zawiera instrukcji package, to jest umi eszczana w pakiecie domyślnym ob ejmują­ cym aktualny katalog i jest widoczna we wszystkich klasach tego katalogu (pakietami zajmiemy s ię dopiero w rozdziale 16). Programy w języku Java dzielą s ię na aplikacje i na aplety. Aplety są to programy wykonywane za pomo cą pr zegląd arki i zajmiemy się nimi w rozdziale 19. Natomiast aplikacje są programami wykonywanymi samo­ dzielnie i przy nauce programowania b ędziemy właśnie tworzyć aplika­ cje, natomiast programowaniem apletów zajmiemy się , mając już pewną wprawę w pro gramowaniu. Trzeba zapamiętać , że w jednym pliku z rozszerz eniem .java może się zn ajdować tylko jedna klasa publiczna (zadeklarowana ze słowem pu­ blic). Klasa publiczna pozwala na jej wykorzystywanie na zewnątrz pa­ kietu , a zatem j eżeli klasa nie j est publiczna, to jest to klasa pomocnicza,

5. WPROWADZENIE DO

30

JĘZYKA

JAVA

którą można w ykorzystywać

tylko wewnątrz paki etu (pakiety s ą omó­ wione w rozd zial e 16) . J eżeli plik zawiera kl asę publiczną, to nazwa t ego pliku musi by ć taka sama jak na zwa klasy (wielkość lit er jest istotna). W pr zypadku aplikacji klasa publiczn a musi z awierać m e t od ę:

public static void main(String[] args) i od niej zac zyna si ę wykon ywanie programu . Jak już wiemy z poprzedniego rozdziału, podstawowy schemat pro­ gramu ma postać:

public class Pierwszy { public static void main(String[] args) {

new Pierwszy();

utworzenie obiektu klasy Pierwszy

}

public Pierwszy()

II konstruktor dla klasy Pierwszy

{

II instrukcje } }

W inn ych plikach umieszczonych w tym samym katalogu mogą być zawarte definicje innych klas i są one a utomatycznie dost ępn e w klasie Pi erwszy. Podczas kompilacji dla wszystkich klas wykorzystywanych w progra­ mie są tworzone pliki z rozszerzeniem .class (d la każdej klasy oddzielny plik) i dopiero te pliki są wykorzystywane przy wykon ywaniu programu prz ez Mas zyn ę Wirtu alną J avy. Szerszym wykorzystaniem i tworzeniem własnych kla s zajmiemy się dopiero w rozdziale 11 (niewielki przykład znajduje si ę też w rozdziale 8), a na razie nasze programy będą zawierać klasę publiczną, w której wszystkie instrukcje są umieszczone w konstruktorze klas y. Przy zapisie programu należy stosować reguły obowiązujące w danym języku programowania. Przede wszystkim t ekst programu powinien być zapisywany w postaci ciągu zna ków. Mi ędzy innymi nie możn a zapisywać

5.1 Program w

języku

uł amków

si ę

t ak, jak

Java

31

to robi na pap ierze .

U ł ame k

x

(y + Z)2

powinien x

by ć

prz edstawiony w sposób

I CCy +

* Cy

+ z))

tak zwa ne s łowa klu czowe. S ą to wyr óżni on e znaczen ie. Sł owa klu czowe nie mogą być używane do ozn aczeni a innych ob iektów progr amu , na przykł ad zm ien­ nych. Zarówno s ł owa klu czowe jak i inne nazwy u żywan e w progr amie m ogą być zapisywane zarówn o m ałymi jak i du żymi lit er ami. J eszcze raz p odkreślmy, że sys t em zwraca uwag ę na wi elkoś ć liter i ni e dopuszcza ich wymiany. Na przykł ad , j eż eli metoda m a n azwę Sprawdzf ), to u życie nazwy sprawd zj) jest b łęd ne. W każd ym miejscu progr a mu mogą wys t ępować kom en t arze czyli do­ wolne opisy. K om en t arz rozp oczyna sekwencj a zna ków 1* , a ko ń c z y *1 . W te n sposób napisany komen t arz m oże zajm ować kilka wierszy. Istnieje też inny sposób za p rojektowania koment arza p ol egaj ący na napisaniu dwóch znaków I I i n as t ępni e d owoln ego te kstu aż do ko ńca wiersza. W

s łowa,

j ęzyku

z)

następujący:

kt ór e

Przykład

J ava

i s tni ej ą

maj ą śc iś le o kreś lo ne

5.1

II to jest właśnie komentarz, można tu II opis x++; II to też jest komentarz

1* taki komentarz

umi eścić

dowolny

może być długi

i zawierać kilka wierszy tekstu

*1

• W tym mi ejs cu wymienimy n ajważni ej sz e zasady obowiąz ujące przy pisaniu komentarzy. Komen tarz powinien być umieszczony wsz ędzi e tam, gdzie istnieje j akakolw iek w ą t pliwo ś ć dotyc ząca dzi ał ani a programu . Po­ nadt o p owinno s ię w kom en t arzu opi sać dzi ałani e wszystkic h metod j ak rów n ież podać opis parametrów formalnych metod. Zn aczeni e waż ni ej ­ szych zm iennyc h wykorzystywanych w programie równi eż wyma ga sko­ mentowania . Z dru giej strony nie należy prz es ad z ać , op is ując oczywiste instrukcje, p oni eważ progr am st anie si ę nie czytelny.

5. WPROWADZENIE DO

32

JĘZYKA

JAVA

Do zidentyfikowania jakiegoś elementu programu używamy nazw. Na­ zwa jest ciągiem znaków, z których pierwszy musi być literą. Deklaracje służą do określenia struktury danych programu. Instrukcje natomiast opi­ sują czynności, jakie powinien wykonać program w celu zrealizowania danego algorytmu. Każda instrukcja prosta musi być zakończona średni­ kiem! Program powinien być zapisywany z wykorzystaniem wcięć tak, aby uwidocznić strukturę poszczególnych instrukcji. Sposób wcinania będziemy prezentować w miarę wykładania poszczególnych konstrukcji języka. Podstawowymi elementami występującymi w programie są stałe i zmienne. Znaczenie ich jest takie samo jak w matematyce. Stałe i zmienne muszą posiadać nazwę i mogą mieć przypisaną wartość. Koniecznie należy zwrócić uwagę na to, by nazwa odzwierciedlała znaczenie danej zmien­ nej czy stałej. I tak nazwa zmiennej do przechowywania wartości sumy pewnych elementów powinna być suma, a nie na przykład w56j . Korzyści ze stosowania stałych szczególnie wyraźnie widać, gdy w kilku wyrażeniach rozrzuconych w różnych miejscach w programie wy­ stępuje ta sama wielkość. Jeżeli wielkość tę umieścimy w stałej , to zmiana jej wartości w jednej deklaracji zostanie uwzględniona we wszystkich in­ strukcjach programu. Natomiast ręczna zmiana tej wielkości w wielu róż­ nych miejscach programu jest pracą żmudną, zupełnie niepotrzebną i na dodatek prowadzącą do pomyłek. Stała jest po prostu zmienną, którą można zainicjować, ale której nie można zmodyfikować. Stałą deklarujemy przy pomocy słowa finał. A oto przykład deklaracji stałej:

final int st1 = 10; Powyższa

deklaracja jest

final int st1;

st1 = 10; II

równoważna następującej

konstrukcji:

przypisać wartość można

tylko raz!

W przypadku większej liczby stałych można je umieścić w jednej kla­ sie, co umożliwi ich wykorzystywanie w innych klasach. Rozważmy przy­ kład.

Przykład

5.2

Stałe wykorzystywane w programie można umieścić

w klasie o nazwie na

przykład

Stale:

5.1 Program w

języku

class Stale { public static public static public static public static

final final final final

Java

int int int int

33

STALAl = 10; STALA2 15; STALA3 = 50; STALA4 = 100;

}

Jak już wiemy, wszystkie pola klasy, do których chcemy mieć dostęp w innych klasach bez utworzenia obiektu tej klasy muszą być statyczne (używamy słowa static). Ponadto, aby zapewnić dostęp do tych stałych w innych klasach, wszystkie stałe muszą być deklarowane ze słowem public. Aby wykorzystać wartoś ć przechowywaną w stałej statycznej w innej klasie wystarczy napisać:

Stale. stalal klasy i po kropce nazwę stałej) . Następująca prosta aplikacja ilustruje wykorzystanie dzonych w klasie Stale. (podajemy

nazwę

Aplikacja 5.1 public class Test { public static void main(String[] args) {

new TestO; }

public Test O {

int w; II deklaracja stałej

final int NMAX = 100;

II wykorzystanie stałych z klasy Stale w = Stale.STALAl + Stale.STALA2;

stałych

zgroma-

5. WPROWADZENIE DO

34

JĘZYKA

JAVA

System.out.println(w); System.exit(O); } } Zwróćmy uwagę, że

w konstruktorze 'Iestf) deklarujemy stałą NMAX o wartości równej 100. Powtórne przypisanie wartości tej stałej jest już niemożliwe. Błędna jest zatem instrukcja:

= 200;

NMAX

• Zmienne wykorzystywane w języku Java mogą być różnych typów. Typ zmiennej definiuje rodzaj wartości, które może ona przyjmować. Na przykład, zmienna typu całkowitego może przyjmować wartości tylko całko­ wite (O, l, -l, 2, -2,3, -3, ...). Zmienne możemy zadeklarować w dowolnym miejscu metody (niekoniecznie na początku), podając nazwę typu i następnie listę zmiennych oddzielonych przecinkami. Przykład

5.3

int i. j ;

1*

zostały

typu

zadeklarowane dwie zmienne o nazwach i oraz j

całkowitego

*1

• Uwaga: wszystkie zmienne zadeklarowane !

5.2

używane

w programie

muszą być

Typy danych

W niniejszym punkcie opiszemy podstawowe typy danych języku J ava,

dostępne

w

5.2 Typy danych

5.2.1

35

całkowite

Typy

W języku Java mamy do dyspozycji kilka typów wymienione w poniższej tabeli.

Nazwa

Zakres

byte short int long

-128 ... 127 -32768 ... 32767 -2147483648 .. 2147483647 -9 * E19 9 * E19

całkowitych,

które



Liczba bajtów reprezentacji 1 2 4 8

0

'00

Deklaracje zmiennych przeprowadza się, podając zmiennych oddzielonych przecinkami.

nazwę

typu i na-

stępnie listę

Przykład

5.4

int k, l ,m;

II

zostały

5.2.2

zadeklarowane trzy zmienne typu

całkowitego

Typy rzeczywiste

Typy rzeczywiste podaje

następująca tabela.

Nazwa

Zakres

float double

3.4 * E38 ... 3.4 * E38 bardzo duży

Możliwe

Liczba znaczących cyfr 6 15

postacie zapisu liczby rzeczywistej

ilustrują poniższe

przy-

kłady:

1.

15.67 zwykły

dzielone 2.

zapis liczby, w którym

część całkowita

i

ułamkowa są

od-

kropką.

83.5E+3 wykładniczy

zapis liczby, w którym po ciągu cyfr (w ciągu tym może występować kropka) podaje się wykładnik. Wykładnik składa

5. WPROWADZENIE DO

36

JĘZYKA

JAVA

się

z litery E oraz liczby, którą oznaczymy symbolem n. Zapis taki interpretuje się w ten sposób, że podaną liczbę w postaci ciągu cyfr mnoży się przez Ifl", Powyższa liczba jest zatem równa 83.5

* 103 =

83500.

Przy okazji omawiania typu rzeczywistego wyjaśnimy pojęcie cyfr znaczą­ cych . Otóż każdą liczbę rzeczywistą zapisuje się w pamięci komputera w postaci dwóch liczb, z których pierwsza oznacza mantysę, a druga cechę. Dana liczba rzeczywista L jest zatem równa (dla uproszczenia podamy reprezentację dziesiętną a nie binarną liczby): L = mantysa * 10cecha Dokładność 6 cyfr znaczących dla zmiennych typu fl.oat oznacza, że mantysa może zawierać co najwyżej 6 cyfr. Liczba 1234567890123456.789 jest więc przechowywana w postaci 0 .123456 E16 co oznacza, że została zaokrąglona do wartości : 1234560000000000 A więc reprezentacja komputerowa rozważanej liczby i na przykład takiej 12345678901999999 jest dokładnie taka sama.

5.2.3

Typ boolean

języku

Java mamy do dyspozycji typ boolean . Zmienne tego typu mogą przyjmować wartości true (prawda) lub false (fałsz) .

W

Przykład

5.5

boolean b1,b2; b1 = false; b2 = true;

5.3 Operacja przypisania

5.2.4

37

Typ char

Zmienne typu char (znakowe) mogą przyjmować wartości będące kodami znaków w Unikodzie (dopuszczalne są znaki narodowe). Zajmują one dwa bajty pamięci i można na nich wykonywać operacje arytmetyczne. Przykład

5.6

char zn;

zn = 'a';

Zmienna zn ma strukcji:

wartość

97 (taki jest kod znaku a). Po wykonaniu in-

zn = zn + 3; Zmienna zn ma

wartość

100;

Operacja przypisania

5.3

Operacja przypisania służy do przypisywania zmiennym pewnej Jest ona postaci: zmienna

=

wartości.

wyrażenie;

Wykonanie tej operacji powoduje przypisanie (podstawienie) wartości wyrażenia (wyrażenie) zapisanego po prawej stronie symbolu równości (=) zmiennej (zmienna) stojącej po lewej jego stronie. Więcej informacji o sposobach konstrukcji wyrażeń zawiera następny podrozdział, a obecnie rozważymy prosty przykład. Przykład

5.7

a = 10; b 15; c = a + b b

=b

+ 1;

II zmienna c przyjmie II zmienna b przyjmie

wartość wartość

25 16

5. WPROWADZENIE DO

38

JĘZYKA

JAVA

Zwróćmy szczególną uwagę na ostatnią instrukcję.

Zawiera ona zmienną b zarówno po lewej jak i po prawej stronie instrukcji przypisania. Realizacja tej instrukcji przebiega ten sposób, że najpierw jest obliczana wartość prawej strony, która następnie jest podstawiana pod zmienną stojącą po lewej stronie operacji przypisania. A zatem do wartości zmiennej b równej 15 dodajemy l i wynik operacji czyli 16 przypisujemy zmiennej b.

w

Uwaga: jak

się

dowiemy w

następnym

podrozdziale, oma-

wianą instrukcję można uprościć pisząc:

b++;

5.4

Wyrażenia i

operatory

Wyrażenia

5 .4.1

Wyrażeniasą

zapisami operacji, które mogą być wykonane na elementach języka. Wyrażenie składa się ze stałych , zmiennych i łączących je operatorów. Kolejnoś ć wykonywania działań określają nawiasy oraz priorytet operatorów.

5.4.2

Operatory arytmetyczne

Skoncentrujemy się teraz na op eratorach arytmetycznych, które mienione w tabeli.

Operator

*

/

+

%

wy-

Znaczenie Mnożenie

Dzielenie Dodawanie Odejmowanie Reszta z dzielenia

Są to operatory dwuargumentowe, co oznacza, na dwóch argumentach. Na przykład, wyrażeni e

x -



że wykonują

operacje

y

ilustruje prawidłowe użycie operatora odejmowania. Oprócz wymienionych w tabeli operatorów istnieją jeszcze dwa operatory jednoargumentowe + oraz - służące do określania znaku liczby (operator - służy ponadto do zmiany znaku wartości zmiennej).

5.4

Wyrażenia

5.4.3

i operatory

39

Operatory relacyjne

Dwuargumentowe operatory relacji beli.

Operator


= -!=



wyszczególnione w

poniższej

ta-

Znaczenie Mni ejszy Mniej szy lub równy Większy Większy

lub równy Równy Nierówny

Jeżeli relacja jest prawdziwa, to jej wartością jest true, natomiast jeśli relacja jest fałszywa, to jej wartością jest false . Warto zwrócić uwagę, że operator sprawdzenia równości to ,,==" (operator przypisania to ,,=").

Przykład

5.8

int a, b; boolean wyn; a = 10; b

= 3;

wyn = a > b;

5.4.4

II zostanie przypisana

wartość

Operatory logiczne

Operatory logiczne podaje

następująca

Operator !

&& II

tabela.

Znaczenie Negacja Koniunkcja Alternatywa

true

5. WPROWADZENIE DO

40

Przykład

JAVA

5.9

boolean a,b,c,d; a true; b = false; c = a && b; II zostanie przypisana d = a II b; II zostanie przypisana

5.4.5

JĘZYKA

wartość wartość

false true

Bitowe operatory logiczne

Bitowe operatory logiczne działają na uporządkowanym ciągu bitów, które jak wiadomo, przyjmują wartości 1 lub O. Ponieważ dokładne omówienie tych operatorów wykracza poza zakres książki, poprzestaniemy tylko na ich wyszczególnieniu w poniższej tabeli.

Operator

& I ~

« »

-

5.4.6

Operatory

Znaczenie Bitowa koniunkcja Bitowa alternatywa Bitowa różnica symetryczna Przesunięcie w lewo Przesunięcie w prawo Bitowa negacja

zwiększania i

zmniejszania

W języku Java mamy do dyspozycji operator ,,++" zwiększający wartoś ć zmiennej o 1 oraz operator ,,--" zmniejszający wartość zmiennej o 1. Jeżeli napiszemy x

= ++a;

oznacza to, że najpierw zwiększamy wartość zmiennej a o 1, a przypisujemy zwiększoną wartość zmiennej x, natomi ast zapis x

następnie

= a++;

oznacza, że najpierw dokonujemy przypisania i dopiero później zwięk­ szamy wartość zmiennej a (reguła ta jest taka sama dla operatora ,,--").

5.4

Wyrażenia

Przykład

i operatory

41

5.10

i nt a,x,y; x = 100; Y= 100; a = 10; x = a++', Y= ++a;

II zmienna x ma II zmienna y ma

wartość wartość

10; 12;

• Operator ,,++" wykorzystan y w postaci

x = ++a; nazywa

x

s ię

prz edrostkowym , nat omi ast zast osowany

n as tępuj ąco:

= a++;

nazywa

s ię

przyr ostkowym. Zwró ćmy jeszcze uwagę , że j e ż eli chce my z większyć tylko war to ś ć pewnej zmiennej o 1 bez dok onywania przypi sywania, to nie ma zn aczenia, którą p ost ać ope rat ora wykorz ystam y. Nat om ias t w przyp adku jednoczesnego dokonywania przypi sywania koni ecznie t rzeba p r z e an aliz ować , czy zastosować ope rator w wer sji pr zed rostk owej czy pr zyr ostk owej. Tut aj p omyłka mo że prowadzi ć do powst ania t ru dnych do wykrycia bł ęd ów. Przykład

a = 10; a++; a=10; ++a;

5.4.7

5.11 II zmienna a ma II zmienna a ma

wartość wartość

11 11

Wieloznakowe operatory przypisania

Wielozn akowe ope ratory pr zypisania pozwalaj ą na skróceni e zapisu w przypadku , gdy za równo po lewej st ronie instrukcji przypi sania j ak i po prawej stronie wys t ępuje t a sama zmienna oraz wykonuj em y pros t ą ope racj ę. Opera t or y te są powszechnie stosowane w j ęzyku J ava i koni eczni e należy je p oznać. S ą one wymieni on e w t abe li zamieszczonej niż ej.

42

5. WPROWADZENIE DO Operator

+= -= *=

1= %= «= »= &= 1= =

-

5.4.8

JĘZYKA

JAVA

Zastosowanie Znaczenie a += b; a = a + b; a -= b; a = a - b; a *= b; a = a * b; a 1= b; a = a I b', a %= b; a = a %b; a «= b; a = a c b; a »= b; a = a» b; a &= b; a = a &b; a 1= b; a=a 1 b', a -= b; a = a - b;

Operator przecinkowy

Operator przecinkowy służy do utworz enia wyrażenia złoż on ego z c i ągu wyrażeń oddzielonych przecinkami. W celu obliczenia wartości takiego wyrażenia kolejno oblicza się warto ś ci wyrażeń składowych od lewej strony do prawej. Wyrażenie złożone użyte w instrukcji przypisania musi być ujęte w nawiasy. Przykład

5.12

int a,b;

a = 10; b = (a++, a+=10);

5.4.9

II zostanie przypisana

wartość

21

Trójargumentowy operator?

Operator ? ma

postać:

? wyrażenie_l : wyrażenie_2 J eżeli unrm ź eni e.loqi czn e przyjmie wartość true, to operator zwraca wartość oblicz on ą z wyrażenia wyrażen ie_l , a j eżeli wyraże ni e_logiczne ma wartość false , operator zwraca warto ść otrzyman ą z obliczenia wyraże­ nia wyrażeni e_2. Operator ? należy używać z dużą ostrożności ą , poni eważ może on uczynić program mniej czytelnym. Z tego względu w książce przeznaczonej do nauki programowania dla początkujących nie będziemy go w ogóle wyrażenie_logiczne

5.5 Instrukcja

złożona

stosować.

Operator ? następnym rozdziale.

5.4.10

43

można

Hierarchia i

zawsze

zastąpić instrukcją

łączność

if

omówioną w

operatorów

Operatory w języku Javajak we wszystkich innych językach programowania posiadają określone priorytety, tzn . jedne operatory są wykonywane przed innymi. Część z tych priorytetów jest taka sama jak w matematyce. Na przykład, mnożenie ma większy priorytet niż dodawanie. W przypadku jakichkolwiek wątpliwości można użyć nawiasów lub sprawd zić priorytet w dokumentacji. Ponadto trzeba wiedzieć, że jedne operatory wiążą od strony lewej do prawej , a inne od strony prawej do lewej. Na przykład, operator przypisania wiąże od strony prawej do lewej, a operator + od strony lewej do prawej. Przykład

5.13

int a,b,w; b

= 1;

a = 10;

w=a

= b;

II zmiennej w zostanie przypisana

wartość

1; 1* Ponieważ operator przypisania wiąże od strony prawej do lewej najpierw zostanie wykonane przypisanie a = b, a później przypisanie w = a *1

5.5

Instrukcja

złożona

Instrukcja złożona umożliwia zgrupowanie dowolnie wielu instrukcji i traktowanie ich jako pojedynczej instrukcji. Takiej grupy instrukcji można użyć wszędzie tam, gdzie składnia języka dopuszcza zastosowanie pojedynczej instrukcji. Instrukcja złożona ma postać: { {Ciąg

}

instrukcji}

44

5. WPROWADZENIE DO

JĘZYKA

JAVA

Instrukcja złożona nie kończy się średnikiem . Wewnątrz instrukcji złożo­ nej można umieści ć każdą instrukcj ę języka Java. Jeżeli instrukcja złożona zawiera deklaracje, to nazywamy ją blokiem . Zakres wido czności zmiennych zadeklarowanych w bloku rozciąga się tylko na ten blok. Jeżeli na przykład mamy następujący blok :

{ int a; a

=

10;

II inne instrukcje }

to

jeżeli

poza blokiem

znajdą się

instrukcje:

int b; b = a;

to

wystąpi błąd

5.5.1

kompilacji z informacją,

że

zmienna a jest nierozpoznana.

Konwersja typów

Java obowiązuje ścisła kontrola typów zmiennych. Na przykw instrukcji przypisania zmienna stojąca po lewej stronie ma typ int, to i wyrażenie po prawej stronie powinno mieć typ int. Kompilator może jednak w niektórych przypadkach dokonać automatycznej konwersji. Jest to możliwe wtedy, gdy jest dokonywana konwersja rozszerzająca, która zachodzi, jeżeli typ przechowujący mniej informacji jest przekształcany w typ mogący przechować więcej informacji. Na przykład w poniższym fragmencie programu: W

języku

ład, jeż eli

int m; float x; m

=

x = x

123; 5.67;

= m; II

konwersja automatyczna, nazywana inaczej standardową, zmienna m jest typu int, a zmienna x jest typu fl.oat i jest możliwe przekształcenie typu int w typ fioat. Gdybyśmy chcieli dokonać przypisania odwrotnego:

jest

możliwa

zachodzi konwersja automatyczna

ponieważ

złożona

5.5 Instrukcja

m = x;

II

BŁĄD

45

KOMPILACJI

to konwersja standardowa nie zajdzie, ponieważ grozi to utratą części informacji i odpowiedzialność za taką d ecyzję musi podjąć programista. Może to zrobić jawnie przy pomocy operatora konwersji , który ma postać : (typ) wyrażenie W powyżs z ej instrukcji przypisania można wykorzystać operator konwersji w sposób następujący: m = (int) x; W tym przypadku część informacji zostanie utracona. Jeżeli zmienna x miała wartość 5.67, to zmiennej mzostanie przypisana wartość 5. Wewnątrz wyrażenia również obowiązuje ścisła kontrola typów zmiennych . Jeż eli zmienne są różnych typów , to gdy tylko jest to możliwe, wszystkie są przekształcane do jednego typu . Wszystkie zmienne (lub stał e) typu char, byte i short są przekształcane do typu int. Jeżeli chociaż jedna zmienna jest typu long, to całe wyrażenie jest przekształ­ cane do typu long. Podobnie całe wyrażenie jest przekształcane do typu float, jeżeli chociaż jedna zmienna jest typu float. Analogiczna reguła obowiązuje dla zmiennych typu double. Rozważmy następujące przykłady.

Przykład

znaczenia

możliwość automatycznego wyz dzielenia dwóch liczb typu int.

5.14 Zilustrujemy teraz

części c ał ko w i t ej

int a,b,w; a = 10; b

4;

w = alb;

II zmiennej w zostanie przypisana

wartość

2

Zmienne a oraz b są typu int, a więc wyrażenie alb będzie też typu int. Warto też sprawdzić, że gdybyśmy przypisywali wynik dzielenia zmiennej typu float: float x; x = alb; to zmienna x

miałaby wartość

przypisując wartość

2.0.

2. O. Wyrażenie alb jest typu int, ale typu int zmiennej typu float otrzymujemy wartość

5. WPROWADZENIE DO

46

Aby zmienna x

zawierała dokładny

JĘZYKA

JAVA

wynik dzielenia wystarczy napi-

sać:

x= (double)a/b; Przykład

5.15 W

przykładzie rozpatrzymy następujące fragmenty

programu: int m,n; = 10; m = n + (int) 1 .23455;

n

W powyższej instrukcji jest konieczne zastosowanie jawnego operatora konwersji, ponieważ nie jest możliwe automatyczne przekształcenie typu do uble (wartość 1.2345) do typu int. Nastąpi obcięcie części dziesiętnej.

double z;

=n

z

Nastąpiła

+ 1. 2345 ;

konwersja automatyczna typu int (zmienna n) do typu do-

uble. by te a;

m

=

120;

a = (by te) m; Zmienna mjest typu int, który może przechowywać więcej informacji niż typ byte. Trzeba zastosować jawny operator konwersji. Żadna informacja nie zostanie utracona (wartość 120 zmieści się w zmiennej typu by te). a

=

120;

Powyższe

przypisanie jest możliwe, mimo że wartość 120 jest typu int. stąd, że już na etapie kompilacji można stwierdzić, że ta warzmieści się w zmiennej typu by te .

Wynika to tość

m = 300; a = (by te) m;

W takiej sytuacji należy zastosować operator konwersji, chociaż w tym przypadku nie ma to sensu, ponieważ nastąpi całkowita utrata informacji.

47

5.6 Klasa String a

= 300;

II

BŁĄD

KOMPILACJI

Powyższą instrukcję się

kompilator uzna za błędną. Wartość 300 nie w zmiennej typu byte, a brak jest jawnego rzutowania typu.

5.6

zmieści

Klasa String

W języku Java do wykonywania operacji na łańcuchach znaków wykorzystuje się wbudowaną klasę String. Klasa ta pozwala na tworzenie obiektów przechowujących teksty. Ponadto klasa String jest wyposażona w szereg metod, które znakomicie ułatwiają przetwarzanie łańcuchów znaków. W celu utworzenia obiektu klasy String wystarczy wykonać instrukcj ę :

=

String x

new String(1'Pierwszy tekst ");

zmienna x jest referencją do obiektu klasy String zawierającego tekst zawarty między znakami " oraz ". Obiekt klasy String można też utworzyć bez użycia operatora new w następujący sposób:

=

String y

"Drugi tekst ";

W powyższej instrukcji utworzenie obiektu klasy String następuje w trakcie jego inicjalizacji. Można też zadeklarować samą referencję do obiektu klasy String, który na razie nie będzie tworzony. Ilustruje to poniższa instrukcja: String z;

W tym momencie referencja z nie odnosi się do żadnego obiektu. Podstawowym operatorem wykorzystywanym dla obiektów klasy String jest operator +. Łączy on łańcuchy tekstowe (i tworzy nowy obiekt), co ilustruje poniższa instrukcj a: z = x +

y;

5. WPROWADZENIE DO

48

JĘZYKA

JAVA

Po wykonaniu tej instrukcji referencja z odnosi s ię do ob iekt u zawierają­ cego ł ańcu ch znaków postaci: "Pierwszy te kst Drugi te kst" Warto od razu po d kreś lić ró żni cę pom iędzy zmien ną typu char a obiektem klasy String . O tóż zmienn e ty pu char m o gą przechowywać tylko jeden zna k. P rzyp isa nie w ar t o ś ci zmiennej tego ty pu odbywa się n ast ępuj ąc o:

char c; c = 'a'; Zwró ćmy uwagę , że

i

bł ędn a by łaby

na

znak umieszczan y jest w pojedynczych apost rofach instrukcja:

p rzy k ład

II

BŁĄD

KOMPILACJI

J e ż eli po jedynczy zna k pr zypisuj emy obiek towi klasy String, to musimy uż y ć podwójnych apostrofów. Poniższ a instrukcja jest zatem błędna:

String w; w = 'a' ;

II

BŁĄD

KOMPILACJI

W języ ku Java raz utworzony obiekt klasy String nie może p odlegać modyfikacj i. Zastanówmy s ię zat em , co oznacza nast ępuj ąca sekwencja instrukcji: String v;

II utworzenie referencji nie II do żadnego obiektu

odnoszącej się

v = abc v = lIklmnll; II

II ;

W momencie przypisania: v

=

II

abc

II ;

jest tworzony obiekt klasy St ring zaw ie rający te kst : abc . Referencja v odnos i s ię do t ego obiekt u. Po przypis aniu: v

=

lIklmn";

5.6 Klasa String

49

referencja v odnosi się do obiektu zawierającego tekst: klmn. Do obiektu "abc" nie odnosi się już żadna referencja i obiekt ten zostanie automatycznie usunięty. Programista nie musi się tym zajmować. Przy pomocy operatora + można tworzyć nowe obiekty klasy String pod warunkiem, że co najmniej jeden operand jest obiektem klasy String. Wartości zmiennych typów podstawowych są automatycznie przekształ­ cane do łańcucha znaków. Dla obiektów innych klas jest wywoływana specjalna metoda toStringO , którą omówimy dopiero w rozdziale 11. Warto teraz przeanalizować kilka prostych instrukcji:

String w,z; w= "abc "; z = w + l' II z odnosi I

do obiektu

zawierającego

tekst : abc 1

z = w + 1 + 1· II z odnosi się do obiektu

zawierającego

tekst: abc 11

z = w + (1 + 1) ; II z odnosi się do obiektu

zawierającego

tekst: abc 2

się

I

z = 1 + 1 + w; II z odnosi się do obiektu zawierającego tekst: 2abc II pierwszy operator + dotyczy wykonania operacji II arytmetycznej Poniższa instrukcja jest błędna, ponieważ brak jest operandu będącego obiektem klasy String.

z

=

1 + 1;

II

BŁĄD

KOMPILACJI

Obecnie pokażemy zastosowanie kilku bardzo użytecznych metod dostępnych w klasie String. Pi erwszą z nich jest metoda length O. Zwraca ona długość łańcucha znaków przechowywanego w obiekcie klasy String. Po wykonaniu następujących instrukcji:

int k; k = x.lengthO;

50

5. WPROWADZENIE DO

JĘZYKA

JAVA

zmienna k zawiera liczbę znaków tekstu przechowywanego w obiekcie, do którego referen cją jest x. Metoda charAt(k) podaje znak stojący na k-t ej pozycji łańcucha. Przykładowe wywołanie moż e mieć postać:

char c; c : : : x.charAt(O); II zmienna c zawiera znak stojący na zerowym miejscu II obiektu, do którego referencją jest x Metoda equalsO sprawdza jej wykorzystania:

równość

dwóch obiektów. A oto

przykład

boolean rowne; rowne : : : x .equals(y); II sprawdzane jest czy teksty, do których referencjami II są x oraz y są równe. Warto podkreślić, że operator == sprawdza po prostu, czy dwie referencje odnoszą si ę do tego samego obiektu. Można zatem uzyskać zupełni e odmi enn e wyniki. Metoda compareTo() pozwala na stwierdzenie, który łańcuch znaków wyst ępuje wcz eśniej (według kolejności alfabetycznej).

int wiekszy; wiekszy : : : x.compareTo(y); Jeżeli

tekst x występuje wcześniej niż y, to metoda compareToO podaj e to dodatnią , a jeżeli oba teksty są równe, to metoda compareToO zwraca O. Metoda indexfrf() podaje miejsce pierwszego wystąpienia tekstu, który jest parametrem aktualnym w tekście będącym obiektem na rzecz którego jest wywoływana metoda. wartość ujemn ą, jeżeli później

int istnieje; istnieje::::: x.indexOf("tekst ll ) ; II w tekście x jest szukane pierwsze II łańcucha: tekst

wystąpienie

Natomiast metoda lastIndexOfO zwraca miejsce ostatniego nia tekstu , który jest parametrem aktualnym.

wystąpie­

5.7 Wprowadzanie i wyprowadzanie danych

istnieje = x.lastIndexOf(ltekst"); II w tekście x jest szukane ostatnie II łańcucha: tekst

5.7

51

wystąpienie

Wprowadzanie i wyprowadzanie danych

Wprowadz ani e i wyprowadzanie danych w pierwszej cz ęś ci książki bę­ dzie bazować na dwóch statycznych metodach showlnput.Dialogf ) oraz showlvlessageDialog j] z klasy JOptionPane. Klasa ta jest umieszczon a w bibliotece Swing, którą trzeba zaimportować na początku programu przy pomocy instrukcji:

import javax.swing.*; Więcej informacji o poleceniu import or az o pakiet ach b ędzi e podane w rozdziale 16, a ob ecnie zilustrujemy wykorzystanie metod showlnputDialogj] oraz show Messagel.iialogf). Podstawowy schemat wykorzystania metody showlnput Dialogf) jest następujący:

String odp; int k; odp = JOptionPane.showInputDialog("Podaj k = Integer.parselnt(odp);

liczbę

gwiazdek");

Metoda showl nput .D ialog f) jest statyczn a i dlatego może być użyta, nawet gdy nie istnieje żad en obiekt klasy. Trzeba tylko podać nazwę klasy i po kropce nazwę metody. Parametrem metody jest tekst wyświetlany w okienku. Met od a zwraca wprowadzony łańcuch znaków. Łań cu ch t en przypisujemy obiektowi klasy String. Aby t ekst przechowywany w obi ekcie klasy String przekształcić w lic zbę całkowitą , należy użyć metodę parselntt) z klasy In t eger (klasa Integer jest klasą p ozwalającą wykorzys tać typ pr osty int w progr amowaniu obiektowym). J eżeli w obiekcie odp nie jest zapisana liczba całkowita lub liczba całkowita ze znakiem, to jest wysyłany wyj ątek Nu mbe rForm at Exce pt ion (wyj ątkom jest poświęcony rozdział 17). Metodę showłvl essagefri alogf) wywołuj emy, pod aj ąc następujące P? rametry:

5. WPROWADZENIE DO

52

JOptionPane. showMessageDialog(okno ,

JĘZYKA

JAVA

inf,tytuł,typ);

gdzie okno - podaje nazwę okna, w którym ma być wyświetlone okienko z komunikatem (jeżeli parametr ma wartość nu l L, to komunikat jest wyświetlany na środku ekranu), inf - wyświetlany komunikat, tytuł - tytuł okienka, typ - typ okienka, może przyjmować wartości: INFORMATIDN_MESSAGE, ERRORJMESSAGE, QUESTION_MESSAGE. A oto przykładowe wywołanie metody: JOptionPane.showMessageDialog(null, "Liczba = II + k, "Liczba gwiazdek", JOptionPane.INFORMATIDN_MESSAGE); Okienko z komunikatem jest wyświetlane na środku ekranu, tytuł okienka to: Liczba gwiazdek, przykładowy wyświetlany komunikat ma postać: Liczba = 8 gdzie 8 jest wartością zmiennej k, okienko ma charakter informacyjny. . Bardzo często metodę showlvlessagefrialogf) wykorzystuje się w ten sposób, że wyświetlany komunikat gromadzi się najpierw w obiekcie klasy String o nazwie na przykład wynik: String wynik; wynik = 1111; wynik += "Liczba wynik += '\n'; wynik += k;

- , -

II.

II dopisanie znaku nowej linii

i jako parametr aktualny podaje się zmienną wynik. Takie postępowanie pozwala gromadzić wyniki w trakcie pracy programu i dokonać zbiorczego ich wyświetlenia w odpowiednim miejscu. Zwróćmy uwagę na możliwość dopisywania do tekstu przechowywanego w obiekcie wynik znaku nowej linii '\n', co znakomicie ułatwia zaprojektowanie odpowiedniego komunikatu. Przykładowe wywołanie metody showlvlessagefrialog(] jest następu­ jące:

JOptionPane.showMessageDialog(null, wynik, "Liczba gwiazdek", JOptionPane.INFORMATIDN_MESSAGE); Wprowadzanie i wyprowadzanie danych przy pomocy metod showlnputDialogt) oraz showlvlcssagefrialogf) jest bardzo wygodne, a co więcej nie ,~~g a zagłębiani. się

w bardziej skomplikowane zagadnienia,

5.7 Wprowadzanie i wyprowadzanie danych Obecnie zwrócimy tylko dzania danych na konsolę:

uwagę

na równie

prostą instrukcję

53

wyprowa-

System.out.println(par); gdziepar może być wyrażeniem liczbowym, łańcuchowym lub logicznym. Istotę tej instrukcji omówimy w rozdziale 18, a obecnie zilustrujemy jej wykorzystanie w prostej aplikacji umożliwiającej wyprowadzenie kodu wciśniętego znaku. W tym celu musimy wiedzieć, że instrukcja x

= System.in.read();

powoduje przypisanie zmiennej x typu int kodu wczytanego znaku i tu ważna uwaga: dokładnie jednego znaku. Na marginesie zauważmy, że nie ma zatem możliwości przy pomocy tej instrukcji wczytania w sposób bezpośredni wartości liczby. Można oczywiście napisać program wczytywania wartości liczb na podstawie wczytanych znaków, ale może być on traktowany tylko jako pouczające ćwiczenie. VV języku Java można również wczytywać całe linie danych , ale tę możliwość omówimy w rozdziale 18. Przy wykorzystywaniu konstrukcji : System.in .read() należy do aplikacji dodać instrukcję importu pakietu java. io import java.io .*; oraz pamiętać,

że

po nazwie metod trzeba

dodać konstrukcję:

throws IOException co pozwoli na wygenerowanie odpowiedniego wyjątku w przypadku wystąpienia błędu (wyjątkom jest poświęcony rozdział 17). A oto odpowiednia aplikacja:

Aplikacja 5.2 import java. io. *; public class Test {

5. WPROWADZENIE DO

54

JĘZYKA

JAVA

public static void main(String[] args) throws IOException {

new Test () ; }

public Test () throws IOException {

int x ; char a;

II podanie kodu wczytanego znaku x = System.in.read(); a = (char) x;

II jawna konwersja typu

System.out.println("Wczytano znak: II + a); System .out.println("Kod znaku : II + x) : } } Reasumując

w p o cz ątkowej nau ce programowania ograniczymy s ię do bardzo pr ostych me tod showl nput fr ialog f) oraz sh owlvlessagefrialogf) z klasy JOptionPane, a do bardziej zaawan sowanych z ag ad n ień przejdziemy pod koni ec książki . Konieczni e tylko należy pami ętać o dołącz eniu do każd ej aplikacji instrukcji:

import javax.swing .* ; umożliwiającej

wykorzystanie biblioteki Swing. Przy okazji om awiania instrukcji wejś cia i wyj ś cia warto podkreślić , ż e wszystkie dane powinny być zaraz po wprowadzeniu wydrukowane lub wyświetl one. Zapobiega t o analizowaniu programu na zup ełnie innych danych niż przewidywane.

Rozdział

6

PODEJMOWANIE DECYZJI W PROGRAMIE 6.1

Instrukcja if... else

Do podejmow ani a decyzji w programie jej post ać jest n ast ępując a:

if

s ł uży

instrukcja if . Najprostsza

(wyrażenie_logiczne)

instrukcja Zwró ćmy uwagę, że unntizenie.loqiczn e występuje wewnątrz nawiasów ( ), o czym trzeba koni ecznie pamiętać. Ponadto in strukcj a może być instrukcj ą prostą lub z ł o ż on ą i dlatego w powy żs z ej konstrukcji nie występuj e śred n ik. J eżeli instrukcja jest prosta, t o średnik jest końcową częścią tej instrukcji. J eż eli war t oś ć wyrażenia logicznego jest true , wówczas jest wykonywana instrukcj a, a w przeciwnym przypadku instrukcja nie jest wykonywana.

Przykład

boolean x; int y; x ;;: true; if (x)

6.1

6. PODEJMOWANIE DECYZJI W PROGRAMIE

56

y = 10; x = false; if (x) y = 10; Przykład

x

II przypisanie nie zostanie wykonane

6.2

= 30; > 10)

i f (x

y x

II przypisanie zostanie wykonane

= 20;

II przypisanie zostanie wykonane

= 5; > 10) y = 20;

i f (x

II przypisanie nie zostanie wykonane

• Stosując instrukcję

if warto pamiętać, że jeżeli wyrażenie_logiczne ma wartość prawdy, to jest wykonywana tylko jedna instrukcja. W przypadku konieczności wykonania kilku instrukcji należy zastosować instrukcję zło­ żoną. Przypomnijmy, że instrukcją złożoną jest ciąg instrukcji ujęty w nawiasy klamrowe. Przykład

6.3

Jeżeli chcemy wykonać dwie instrukcje:

min = x; nr = i; gdy zachodzi warunek min max) max = liczba; else if (liczba < min) min = liczba; odp JOptionPane.showInputDialog("Podaj liczba = Integer.parseInt(odp);

liczbę");

}

JOptionPane.showMessageDialog(null, "max = "+ max, "Maksimum liczb",JOptionPane.INFORMATION_MESSAGE); JOptionPane .showMessageDialog(null , "min = "+ min, "Minimum liczb",JOptionPane.INFORMATION_MESSAGE); System.exit(O);

II

zakończenie

pracy aplikacji

} }

Przykład 7.3 Rozważmy następujący problem. Należy wydrukować tablicę zawieraj ącą co pi ątą sumę spośród sum koLejnych liczb całkowi­

tych od 1 do 50. Wynik wykonania pro gramu powinien

liczba 5 10 15

20 25 30 35

40 45 50

mieć postać :

suma 15 55

120 210 325 465 630 820 1035

1275

Algorytm rozwiązania tego problemu zapiszemy najpierw w pseudo­ kodzie ponownie na bardzo niskim poziomie szczegółowości.

7. ORGANIZACJA OBLICZEŃ CYKLICZNYCH

68

Algorytm 7.2 tablicy przypisz zmiennej suma wartość O przypisz zmiennej licznik wartość O podczas gdy (licznik jest mniejszy od 50)

wyświetl nagłówki

{

licznika o 1

sumy o wartość licznika

jeśli licznik jest wielokrotnością 5 to

wyświetl wartość licznika i sumy

zwiększ wartość

zwiększ wartość

}

Zmianę wartości

licznik

licznika dokonuje instrukcja

= licznik + 1;

którą można zapisać

w prostszy sposób:

licznik++; a kontrolę tego, czy licznik nie przekroczył podanej wartości, przepro­ wadza się w pętli while. Zwróćmy uwagę na sposób realizacji warunku, że licznik jest wielo­ krotnością 5. W języku Java konstrukcja tego warunku jest następująca: licznik

% 5 ==

O

gdzie operator %podaje resztę z dzielenia przez liczbę 5. Jeżeli obliczona reszta jest równa zeru, oznacza to, że licznik dzieli się przez 5. Powyższy algorytm realizuje aplikacja 7.3.

Aplikacja 7.3 import javax .swing.*; public class CoPiata {

7.2 Instrukcja do while

69

public static void main(String[] args)

{

new CoPiataO;

}

public CoPiataO {

int suma, licznik;

String odp, wynik;

wynik = 1111; suma = O;

licznik = O;

while (licznik < 50) {

licznik++;

suma += licznik;

if (licznik % 5 == O)

wynik += licznik +

II

II

+ suma + '\n';

}

JOptionPane.showMessageDialog(null, wynik, II liczba suma", JOptionPane.INFORMATION_MESSAGE); System.exit(O); } }

7.2

Instrukcja do while

Składnia

instrukcji do while jest

następująca:

do

instrukcja while (wyrażenie_logiczne); (może być złożona) jest wykonywana tak długo, jak długo wartość wyrażenia (wyrażenie_logiczne) jest równa true. W przypadku,

Instrukcja

gdy wartość ta będzie równa false, to wykonywanie instrukcji do ... while kończy się. Wynika stąd, że instrukcja jest zawsze wykonywana

7. ORGANIZACJA OBLICZEŃ CYKLICZNYCH

70

co najmniej jeden raz i to jest podstawowa

różnica pomiędzy omówioną

wcześniej instrukcją while.

Przykład 7.4

W przykładzie podamy szkielet programu ilustrujący technikę pozwalającą na wielokrotne wykonanie pewnego zbioru instruk­ cji. Kluczową instrukcją tej konstrukcji jest instrukcja do...while:

do {

II zbiór instrukcji }

while (czyWykonywac()); gdzie czyWykonywac() jest wywołaniem pewnej metody, w której jest sprawdzany warunek z akończenia pętli do ... while. Przykład ści ciągu

7.5 W przykładzi e podano aplikację wyznaczania długo­ liczb zakończ onego zerem. Zero jest traktowane jako eleme nt

CIągU .

Aplikacja 7.4 II wyznaczanie

długości ciągu

liczb

import javax .swing.*; public class Dlugosc { public static void main(String[] args)

{

new Dlugosc () ;

}

public Dlugosc () {

int liczba, dlugosc.;

String odp;

dlugosc

= O;

7.3 Instrukcja for

71

do { odp = JOptionPane.showInputDialog("Podaj liczba = Integer.parseInt(odp);

liczbę");

dlugosc++;

} while (liczba != O);

JOptionPane. showMessageDialog(null, I~ "+ dlugosc, "Długość ciągu", JOptionPane.INFDRMATIDN_MESSAGE); System .exit(O); } }

7.3

Instrukcja for

Instrukcję

for stosuje się w przypadkach, gdy można z góry określić liczbę wykonań pętli. Stosuje się ją zwłaszcza do wykonywania operacji na ta­ blicach i dlatego w rozdziale 8 są podane liczne przykłady wykorzystania instrukcji for. Postać tej instrukcji j est następująca : for

(wyrażeniel; wyrażenie_logiczne; wyrażenie2)

instrukcja Powyższa instrukcja

jest

równoważna konstrukcji:

wyrażeniel ;

while (wyrażenie_logiczne) { instrukcja wyrażenie2;

}

Azatem najpierw jest obliczana wartość wyrażeniel, co powoduje na ogół wyznaczenie wartości początkowej zmiennej sterującej. Następnie jest ob­ liczana wartość unjra źenie.loqiczne i jeżeli jest ona równa true (prawda), to jest wykonywana instrukcja oraz wyrażenie2, w której przeważnie na­ stępuje zmiana wartości zmiennej sterującej pętli.

72

7. ORGANIZACJA OBLICZEŃ CYKLICZNYCH

Przykład

7.6

for (i=l;i 84 < 84,87 > 86 Zauważmy , że

Odpowiedź

za za za za za

m ał o m ało m ał o m ał o mał o

z gadni ęt e

nawet je żeli zakres liczb , z kt óry ch mamy z gadywać , wynosi 1024, to dana liczba zost anie od g adnięt a po co najwyżej 10 py­ taniach . Wynika to z faktu , że po każd ej odpowiedzi dwukrotnie zmniej­ szamy int eresujący nas zakres. Spr awdźmy, ż e faktyczni e wystarczy dzie­ sięć prób. Poniżej podano wielko ś ci zakresów prz y kolejnych pytaniach.

8.2

Przykłady

133

Zapytanie 1 2 3 4 5 6 7 8

Wielkość

9

10

zakresu I 512 256 128 64 32 16 8 4 2 1

Jak w i dać, co n aj wyż ej w dz ies iątej próbie wi elko ść za kresu wyn osi 1, a więc liczba zosta ła odgad n ięta . Obecnie zilust ruje my zastosowanie wysz ukiwania bina rnego do znale­ zienia liczby w tablicy up o r z ądkowan ej. Roz waż my tab licę z z aw ar t o ś c i ą poszczególnych eleme ntów p od aną na rys . 8.6A. A)

B)

~ 89 ! 93@§] 6.

CI

Rysunek 8.6: Ilu st racja wyszukiwa nia bina rnego

Niech sz ukaną li cz b ą będz ie 95. Po dczas wyszuki wania wane n as t ępuj ąc e operacje.

będ ą

wykony­

1. Ś ro dkowy element o warto ś ci 45 zosta nie porówn an y z wartośc ią 95 (w pr zyp adku parzys tej liczby element ów ta blicy je st wyb ierany jeden z d wóch śro d kowych eleme ntów). W wyniku tego p or ównania dalszemu przeszuk iwaniu b ę d zi e pod legała część tablicy po kazana na rys. 8.6B.

134

8. WYKORZYSTANIE TABLIC

2. Wybieramy wartość jednego z dwóch elementów środkowych (n­ parzyste). Niech tą wartością będzie 89. W wyniku porównania z szukaną liczbą stwierdzamy, że jest ona większa. A zatem do dal­ szego przeszukiwania wybierzemy tablicę leżącą na prawo od ele­ mentu o wartości 89 (rys. 8.6C). 3. Wybór elementu środkowego w tym kroku algorytmu szukiwanie. Liczba 95 została znaleziona.

kończy

prze­

Uwaga: jeżeli wybrana część tablicy jest pusta, oznacza to, że szukanego elementu nie ma w tablicy. Sformułujemy

teraz algorytm wyszukiwania binarnego, bardziej pre­ cyzyjnie zapisując go w pseudo-kodzie.

Algorytm 8.12 ustaw do

przedział początkowy

od O do n-l

{ znajdź

środek przedziału

if (znaleziono zapamiętaj

else

if

liczbę)

fakt znalezienia liczby

(środkowa wartość przedziału

od liczby) za przedział przyjmij

jest mniejsza

prawą część rozważanego

przedziału

else za

przedział

przyjmij

lewą część rozważanego

przedziału

}

while (nie znaleziono liczby i przedział nie jest pusty) czy liczba została znaleziona

wyprowadź informację,

Przed sformułowaniem programu zastanowimy się jeszcze nad dokład­ niejszym sprecyzowaniem zdań występujących w pseudo-kodzie. Począ­ tek rozważanego przedziału będziemy definiować przy pomocy zmiennej

8.2

Przykłady

135

lewy, koniec przedziału przy pomocy zmiennej prawy, a środek prze­ działu przy pomocy zmiennej srodek. Środek przedziału wyznaczymy następująco:

sro dek =

lewy + prawy

2

.

'

Fakt znalezienia liczby zapamiętamy w zmiennej wynik typu int, która na początku algorytmu przyjmie wartość O, a w momencie znalezienia liczby wartość 1. Zdanie pseudo-kodu za przedział przyjmij prawą część rozważanego przedziału zapiszemy jako: lewy

= srodek

+ 1;

Oznacza to, że lewy koniec nowego przedziału przyjmie wartość środkową plus jeden, natomiast prawy koniec tego przedziału pozostaje bez zmian. Zdanie pseudo-kodu za przedział przyjmij lewą część rozważanego przedziału zapiszemy w postaci: prawy

= srodek

- 1;

Oznacza to, że prawy kraniec nowego przedziału przyjmie wartość środ­ kową minus jeden, natomiast lewy kraniec pozostaje bez zmian. Przedział nie jest pusty, jeżeli lewy 7; }

public boolean Sprawdz() {

return jednostki < 20; } }

Podobnie jak dla kla sy NaukowiecZbior klasa StudentZbior zawiera dod atkow ą d ekl ar acj ę pól: nazwisko, imie, ksiazki oraz są wprowadzone drobne ró żnice w definicjach niektórych met od w stosunku do klasy Student. A ot o aplikacja ilustrująca wykorzystanie zaproj ektowanych klas:

15. INTERFEJSY

321

Aplikacja 15.1 import javax .swing.*; import java.util.*; public class Pojemniklnter { public static void main(String[] args) {

new Pojemniklnter(); }

public Pojemniklnter() {

String liczby = "II; II utworzenie dwóch obiektów klasy NaukowiecZbior NaukowiecZbior nl :: new NaukowiecZbior("Kowalski" , "Jan", 5, 180), n2 = new NaukowiecZbior("Piotrowski" ,"Marcin" ,9, 200);

II utworzenie dwóch obiektów klasy StudentZbior StudentZbior sl = new StudentZbior("Wiśniewski" , "Piotr", 9, 25), s2 = new StudentZbior("Jankowski" , "Adam ll ,9,30) ;

II dodanie ważnych liczb dla poszczególnych obiektów II wykorzystywane są metody z klasy ZbiorLiczb nl .Dodaj(352678); nl .Dodaj(354278) ; n2 .Dodaj(452389); sl .Dodaj(456734); sl .Dodaj(567832); s2.Dodaj(432398) ;

322

15. INTERFEJSY

II II

utworzenie tablicy zawierającej referencje typu Osobalnter Osobalnter[] tab = new Osobalnter[lO];

II wpisanie do tablicy referencji na utworzone obiekty tab [O] = ni; tab [1] = n2; tab [2] = s l ; tab [3] = s2; II

wyprowadzenie informacji o poszczególnych obiektach for (int i = O; i < 4; i++) { II ustalenie typu referencji i wpisanie do II obiektu liczby informacji podanej przez II metodę Wszystkie() if (tab[i] instanceof NaukowiecZbior) liczby = «NaukowiecZbior) tab[i]) .Wszystkie(); else if (tab[i] instanceof StudentZbior) liczby = «StudentZbior) tab[i]) .Wszystkie(); JOptionPane.showMessageDialog(null, tab [i] .PodajNazwisko() +" "+ liczby, tab [i] .Podaj Stanowisko () , JOptionPane.INFORMATION_MESSAGE); }

II

utworzenie pojemnika klasy ArrayList ArrayList osoby = new ArrayList();

II wpisanie referencji do pojemnika osoby .add Cm ) : osoby.add(s1) ; osoby.add(s2) ; osoby.add(n2) ; II II

określenie liczby obiektów przechowywanych w pojemniku int liczba = osoby.size();

15. INTERFEJSY

323

for (int i = O; i < liczba; i++) { II przypisanie referencji do i-tego obiektu Object obiekt = osoby.get(i); II jawna konwersja typu Osobalnter os = (Osobalnter) obiekt;

II II II

ustalenie typu referencji i wpisanie do obiektu liczby informacji podanej przez metodę Wszystkie() if (os instanceof NaukowiecZbior) liczby = ((NaukowiecZbior) os) .Wszystkie(); else if (os instanceof StudentZbior) liczby = ((StudentZbior) os) .Wszystkie();

II wyprowadzenie informacji o obiekcie JOptionPane.showMessageDialog(null, os .Wyprowadz() + '\n'+ liczby, os .PodajStanowisko(), JOptionPane.INFORMATION_MESSAGE); }

System.exit(O); } } Powyższ a

aplikacja zost ała zaproj ektowana w sposób analogiczny jak aplikacja 13.3 z rozdziału 13, w której był y ilustrowane polimorficzne wywołania metod. I tu r ówni eż warto zwr ó ci ć uwagę na polimorficzne wywołani a. Otóż referencje ni , n2, s i , s2 można wpisać do t ablicy tab typu Osobalnter. Następujące wywołania: tab [i] .PodajNazwisko() tab [i] . Podaj St anowi sko () umieszczone w metodzie showjvl essagefrialogf) zachodzą w sposób polimorficzny. Jest wywoływan a metoda z tej klasy, której typu jest referencja umieszczona w elemencie tab [i] . Natomi ast , j eżeli chcemy wywołać metodę na przykład Wszystkie O z klasy ZbiorLiczb, to nie da si ę t ego dokonać w sposób polimorficzny: tab[i] .Wszystkie()

II

BŁĄD

KOMPILACJI

15. INTERFEJSY

324

Metoda Ws zystkie() jest z klasy ZbiorLiczb, natomiast tablica tab jest ty pu ZbiorInt er. Polimorficzne wywo łan ie m oże z aj ść ty lko dla klas implementuj ąc ych interfejs Osobal nter. Oczywiście .nie ma ż adn e go pr oblemu z wywoł ani em: nl .Dodaj(352678) ; ni jest refer en cj ą do obiektu klasy Nau kowiecZbior i są dzi edzi czone metody z klasy ZbiorLiczb. Aby dla element u tablicy tab [i] wywołać j akąś metodę z klasy ZbiórLiczb t rzeba naj pierw s p raw dz ić, j akiego typu jest referencj a tab [i]. Można tego d okon ać przy pom ocy operatora instanceof wykorzystanego w sposób n as t ępuj ąc y : tab [i] instanceof NaukowiecZbior Wynikiem jest war t oś ć true , j eż e li tab [i] j est typ u Nau kowiecZbior i false w przeciwnym przypadku. Jeże l i ju ż wiemy, j aki ego typ u jest tab [i] , to wystarczy d okon ać jawnej konwersji w sposó b n ast ępuj ący : liczby = ((NaukowiecZbior) tab[i]) .Wszystkie(); W pisa nie do ob iekt u liczby informacji wyprowad zonej pr zez Wszystkie() d oko n al iśmy w sposób następ ujący :

meto d ę

if (tab[i] instanceof NaukowiecZbior) liczby = ((NaukowiecZbior) tab[i]) .Wszystkie( ) ; el se if (tab[i] instanceof StudentZb ior) liczby = ((StudentZb ior) tab[i]).Wszystkie() ; W pod obny sposób t rzeba postępować w przy padk u przechowywania referencji w po je mniku osoby klasy ArrayList . Wywoł ani a metod os .Wyprowadz O i os. Podaj Stanowisko O zacho d z ą w sp osób polimorficzny, natom iast przed wywoł an i em metody Wszystki e() trzeba u st alić typ konkretnego obiekt u, do kt órego r eferen cj ą jest os. Sama referencja os jest typu Oso balnter, co wynika z j awnej konwersji typu: Osobalnter os

= (Osobalnter) obiekt;

Referencja obiekt musiał a być ty pu Object, pon i eważ pojemnik klasy ArrayList nie posiada inn ej inform acji o ty pie referencji.

Rozdział

16

PAKIETY Paki ety t o nic in nego j ak bibliot eki zawie raj ące pliki z definicjami klas. Aby umi e ści ć kl asę w o k reś l ony m paki ecie, n al eży jako pierw sz ą p od ać instrukcj ę :

package nazwa_pakietu; Klasy nie z awi eraj ąc e de kla racji package n ależą do paki etu d omy śl­ nego (bez nazwy). W śr o dow is k u Windows pakie t d omy śln y to bi eżący katalog (w innych środ owiska ch paki et d omyślny mo ż e być zd efiniowany inaczej) . Do tej pory wszystkie definicje klas programów pr z ykł adowych były umieszczane w pakiecie d omyślnym i nie zawi er ały deklaracji pac­ kage .

Pakiet nazwan y m oże zawi er ać podpaki et , kt óry z kolei moż e zawie­ rać n astępny podpakiet (nazwa podpaki etu jest umieszczana po kropce). Do tej pory pr zy pom ocy ins trukcji import dokonywaliśmy przył ąc z e­ nia paki etu javax.swing (paki et z awi eraj ący bibliotekę Swing dostępną w ś rod ow i sk u uruchomieniowym) pisząc:

import javax .swing.*; P owyż sz a

instrukcj a powoduj e udost ępni eni e wszystkich kla s umieszczo­

nych w paki ecie j avax.swing.

W niektóry ch progr am ach b ęd ziemy wykorz ystyw ać paki et java x.swing.­ event, który jest pod paki etem paki etu javax .swing będąc e go z kolei pod­ pakietem pakietu j avax. P rzył ąc z eni e do pro gramu pakietu javax.swing. eve n t odbywa się przy pomocy instrukcji:

16 . PAKIETY

326

import javax .swing .event.*; Wart o za pa miętać, że hiera rchiczn a strukt ura pakietów może być pr zechowywa na w róż ny sposób na dysku . Typowy sposób to st ru kt ura katalogów, gdz ie kolejne po dpak iety są przechowywane w kolej nych pod­ katalogach o takich samych nazwach jak nazwa podp ak ietu . Aby dalsze rozważ ani a u c zy ni ć bardz iej kon kretnymi , pr zyjmiemy, że ur uchamiamy programy w ś rodowis k u 'W indows, w kt órym obowiąz uje w łaś n ie taki sposób pr zechowywania pakiet ów. Nie dotyczy to jedn ak paki et ów do­ s t ępnych w ś rodow isk u uruchomi eni owym w wersji 2 j ęzy ka J ava. Pa­ kiety standardowe są przechowywane w plikach z rozszer zeni em .jar i są um ieszczone gdzi e ś w kat alogu z aw i erając ym ś ro dow is ko uruchomieniowe (w katalogu tym nie zna jdz iemy podkat alogu np. javax). Dl a wszystkich wersji j ęzyka J ava 2 pakiety standardowe są dostęp ne a uto matycznie bez dokonywani a ż ad nych dodatkow ych d zi ał ań . Zu p ełni e in aczej ma s ię sprawa z pakiet ami tworzo nymi przez pro­ gram istę . W tym pr zyp adku t rze ba u s t awić od powied nio z m i en n ą syste­ m ow ą o nazwie CLASSPATH. W sys te mach Wi ndows poc zy nając od wersji 98, aby u s t awić tę z m i en ną, t rzeba wykon ać n as tępuj ąc e operacje: 1. Start.

2.

W y br ać opcję

Ustawienia.

3.

W y br ać o pcję

Panel sterowania.

4.

Nac is nąć i ko nę

5.

Wybrać kar t ę

6.

W y br ać

7.

D od ać z m i e n n ą CLASSPATH

Syst em.

zaawansowane.

zmienne

środowisko w e .

i

u s t aw i ć

jej

w ar toś ć .

Zmi enna CLASSPATH podaj e kat alogi, kt óre trzeba prz egl ąd ać , aby od naleźć dany pakiet. P rzy k ład owe ustawienie zmi enn ej CLASSPATH mo że być n as t ęp uj ące : . ;C :\JAVA_PRD;C:\KW\JAVA

16. PAKIETY

327

Oznacza to, że w przypadku napotkania instrukcji importu pakietu, który nie jest standardowy, kompilator będzie przeglądał katalog bieżący ozna­ czony kropką oraz katalogi C : \JAVA-.PRO i C : \KW\JAVA. Przypomnijmy sobie teraz, jak w rozdziale 8, 9 i 10 wykorzystywa­ liśmy klasę Tablice zawierającą metody umożliwiające wprowadzenie i wyprowadzanie danych z tablic. Ponieważ nie znaliśmy jeszcze wtedy techniki tworzenia pakietów, plik Tablice.java z definicją klasy Tablice był umieszczony w każdym z katalogów ROZ_B, ROZ_9, ROZ_lO. Po­ stępowanie takie jest usprawiedliwione w nauczaniu programowania po to, by nie wprowadzać zbyt dużo wiadomości od razu, ale całkowicie nie do przyjęcia w praktycznym programowaniu. Każdy prawdziwy pro­ gramista w tej sytuacji powinien utworzyć własny pakiet o nazwie na przykład bibl i w tym pakiecie umieścić klasę Tablice. Aby to zrobić, należy wykonać następujące czynności:

1. W katalogu C : \JAVA-.PRO zawierającym programy z książki utworzyć podkatalog bibl,

Uwaga: wielkość liter jest istotna. Nazwa podkatalogu musi być taka sama jak nazwa biblioteki.

2.

Przekopiować Dodać

jako

do katalogu C : \JAVA-.PRO\bibl plik Tablice.java.

pierwszą następującą instrukcję:

package bibl; 3.

Zmienną CLASSPATH ustawić

na:

Aby przetestować naszą bibliotekę, trzeba uruchomić dowolny pro­ gram wykorzystujący klasę Tablice z katalogu, w którym nie ma pliku Tablice .java. Można to zrobić na przykład w ten sposób: utworzyć ka­ talog Test, przekopiować do niego plik Babell.java, w pliku Babel1.java dodać instrukcję:

import bibl; i

uruchomić aplikację.

bliotekę

W tym przypadku kompilator, aby znaleźć bi­ o nazwie bibl, będzie przeszukiwał katalogi wyszczególnione w

16. PAKIETY

328

zmiennej CLASSPATH w celu znalezienia podkatalogu o nazwie bibl. Po­ nieważ w zmiennej CLASSPATHjest umieszczony katalog c: \JAVA2RO, a w nim znajduje się w podkatalogu bibl nasz pakiet, to wszystko za­ kończy się poprawnie. Warto jeszcze wiedzieć, że zamiast stosowania instrukcji import można podawać nazwę klasy poprzedzoną nazwą pakietu. Na przykład, wywo­ łanie metody czytajTab() z klasy Tablice może odbywać się następująco:

bibl.Tablice.czytajTabex); Przypuśćmy teraz , że chcemy utworzyć pakiet o nazwie aaa. bbb bez zmiany wartości zmiennej CLASSPATH. W tym celu trzeba utworzyć pod­ katalog aaa wewnątrz katalogu C : \JAVAYRO, a wewnątrz katalogu aaa utworzyć podka.talog bbb. Wszystkie klasy, które chcemy umieścić w pakiecie aaa. bbb powinny zawierać instrukcję:

package aaa.bbb; a

wszędzie

tam , gdzie chcemy

wykorzystać

pakiet aaa. bbb, powinniśmy

zastosować instrukcję:

import aaa.bbb; Jeszcze raz podkreślmy, że będzie to CLASSPATH będzie zawierała warto ść:

działać

tylko wtedy, gdy zmienna

którą trzeba ustawić samodzielnie (sposób postępowania może być trochę odmienny dla różnych wersji systemu Windows). W przypadku błędów przy wykorzystywaniu własnych pakietów na­ leży sprawdzić , czy wi elkość liter w nazwie pakietu i nazwie podkata­ logu jest taka sama i czy prawidłowo jest ustawiona zmienna systemowa CLASSPATH. Korzyści ze stosowania pakietów są oczywiste. Można raz napisaną klasę umieścić w pakiecie i przy pomocy instrukcji import wykorzysty­ wać ją w innych programach. Ponadto można uniknąć konfliktów nazw w przypadku klas projektowanych przez różnych programistów. W tym celu trzeba zapewnić unikatowość nazw pakietów poprzez wykorzystanie na przykład internetowych nazw dziedzin. Pierwsza część nazwy pakietu

16. PAKIETY

329

może być tworzona w oparciu o elementy nazwy dziedziny występujących w odwrotnej kolejności. Na zakończenie przypomnijmy jeszcze zakres widoczności dla klas i interfejsów oraz składowych klasy. W przypadku klas i interfejsów, jeżeli są one zadeklarowane jako pu­ bliczne (public), to są dostępne w kodzie spoza danego pakietu. Klasa lub interfejs zadeklarowane bez słowa public są widoczne wyłącznie we­ wnątrz danego pakietu. Składowe klasy zadeklarowane bez żadnego słowa są dostępne w ca­ łym pakiecie dla wszystkich klas znajdujących się tam. Podobnie jest dla składowych zadeklarowanych ze słowem protected i public. Reasumu­ jąc w danym pakiecie są widoczne wszystkie składowe nie zadeklarowane ze słowem private.

Rozdział

17

WYJĄTKI J ęzyk

J ava , jak każd y nowoczesn y jęz yk programow ani a , dy sponuje me­ chanizme m obs ł ugi wyj ątków , gdzie pr zez wyj ątek rozumiemy s y tuację nadzwy cz ajn ą wymagając ą pr zywró cenia normaln ego stanu wykonywa­ nia pr ogramu . Przykładami sytuacji w yj ątkowych m o że by ć: pr óba usu­ ni ęci a nie i s tni ej ącego pliku, błędny form at wpr owadz an ych danych , wy­ c i ąg n ięc ie pierwiastka z liczby ujemnej czy też pr zekr oczeni e zakresu ta­ blicy. Sytuacja wyjątkowa pol ega na tym , że w danym m om enci e jest za ' m ał o inform acji , aby podjąć stosowne d ział ani a. Przerywa s ię wt edy dzia­ ł anie dane go bloku i przekazuje problem do ro zw i ąz ani a gdz ie indzi ej. A zate m wyj ątki nie powinny być stosowane w zwykły ch sytuacjach , gdzie d okł adni e wiad om o, co zrobi ć z pojawiającym s ię bł ęd em. W j ęzyku J ava wyjątki są obiektami klas p o chodzących od klasy Throwabl e. Wyj ą tki zgłaszan e prz ez syste m uruchomi eniowy są obiek­ t ami klas po ch odzących od klas RuntimeException or az Error (obie klasy p o ch odz ą od Throwable) i s ą wyjątkami niekontrolowanymi. Oznacza to, że w każd ej metodzie jest m o żliwoś ć poj awieni a s ię teg o typu wyj ąt ku bez żadn ej dodatkowej deklaracji . Wyj ątki zgłaszan e pr zez sys t em uru­ chomieniowy to na przykład Arraylnd exOutOfBoundsException czy t eż ArithmeticException . Pierwszy wyj ątek jest zg łaszany gdy zost ani e prze­ kroczony zakres tablicy, a drugi przy wykonaniu bł ędn ej op eracji aryt­ metycznej powstał ej na przykład w wyniku dzielenia pr zez O. Programista może utworzyć własną klasę p o ch od zącą od klas y Excep­ tion do generowania własnych wyjątków. Wyj ątki t ego t ypu są wyjątkami kontrolowanymi, co znaczy, że kompilator sprawdza, czy dana metoda zg ł asz a tylko te wyjątki , które są wymi eni one w deklaracji metody we

17.

WYJĄTKI

331

frazie throws . W j ęzyku Java blok kodu, w którym m ogą hyć zg ł as z ane wyjątki, jest oznaczany pr zy pomocy słow a kluczowego try. J eżeli w yj ąt ek jest generowany przez Maszynę Wirtualną J avy, to jego zgłószeni e następuj e automatycznie, natomiast gdy wyją t ek generuj e pro gram, wówczas jest wymagane użyci e słowa throw. Obsługa wyjątków j est dokonywana w bloku poprzedzonym słowem catch(}. Bloki catchf ] muszą występowa ć hezpo śr ednio za blokiem try i może by ć ich dowolnie dużo. A oto schemat fragm entu programu, w którym możemy dokonywać obsługi wyjątków:

try { }

catch

(typ_wyjątku

ident)

(typ_wyjątku

ident)

{ }

catch {

}

finally { }

Blok umi eszczony w klau zuli finally jest wykon ywany zawsz e, nie­ od t ego czy nastąpiło zg ł osz e n ie wyjątku. Natomiast jeżeli na­ stąpiło zgłos z enie wyjątku , to są przeszukiwane kolejn e hloki catchf ) aż do znalezieni a takiego, w którym parametrem jest obiekt klasy wyjątku bąd ź t eż jego klasy bazowej. Wprowadzone poj ęcia zilustrujemy paroma prostymi przykładami.

zależnie

Przykład 17.1

Celem przykładu jest pokazani e, w jaki sposób można przez Maszynę Wirtualną J avy. następujący fra gm ent:

przechwycić wyjątki zgłaszane Rozważmy

332

17.

WYJĄTKI

if ((i/2)*2 ;; i)

w ; t ab l i.L' t O:

else

w ; tab[i]/O;

Widać, że dla parzystej wartości zmiennej i będzie następowało dzie­

lenie przez O. System wygeneruje wtedy wyjątek ArithmeticException i nastąpi przerwanie pracy programu. Można temu zapobiec, umieszczając powyższy fragment w bloku try:

try {

if ((i/2)*2 ;; i)

w ; tab[i]/10;

else

w ; tab [i] /0 ; JOptionPane.showMessageDialog(null, ""+ w, "Wynik operacji", JOptionPane.INFORMATION_MESSAGE); }

a blok catcht )

zaprojektować następująco :

catch(ArithmeticException ob) {

JOptionPane.showMessageDialog(null, ""

"Blad operacji arytmetycznych",

JOptionPane .ERROR_MESSAGE);

}

Blok ten obsłuży wyjątek klasy ArithmeticException. Obsługa w tym przypadku jest wyjątkowo prosta i polega tylko na wyświetleniu od­ powiedniego komunikatu. Można tu jednak z amieścić znacznie bardziej skomplikowane operacje. Pokażemy teraz jak można obsłużyć wyjątki różnych klas . W tym celu niech wykorzystywana tablica zawiera 5 elementów:

int[] tab; {10,20;30,40,50}; a w instrukcji for indeks tablicy zmieniamy od O do 6:

for (i;O; i