java_01.pdf

(259 KB) Pobierz
Microsoft Word - roz_1.doc
Jacek Rumi ń ski - J ę zyk JAVA – Rozdzia ł 1
Rozdział 1 Tworzenie i obsługa programów
1 . 1 Klasy obiektów
1 .2 Aplikacje
1 .3 Aplety
1 .4 Aplikacja i aplet w jednym kodzie
1 .5 Interpretacja, kompilacja i obs ł uga klas w Javie
1 .6 Wyj ą tki
1 .7 Klasy wewn ę trzne
1.1 Klasy obiektów
Ponieważ Java jest językiem obiektowym operuje na pojęciach ogólnych.
Znane z historii filozofii pojęcie uniwersalii, a więc pewnych klas ogólnych bytów np.
człowiek, małpa, rycerz Jedi, jest stosowane w Javie (jak i w innych językach
obiektowych). Klasa bytów (class) określa opis bytu (stałe, zmienne, pola) oraz jego
zachowanie (metody). Przykładowo klasę ludzi można opisać poprzez parametry:
kolor oczu, rasę, kolor włosów, itp., (pola klasy) ; oraz poprzez zachowanie: chodzi,
oddycha, itp, (metody klasy). Obiektem jest konkretna realizacja klasy, a więc np.
konkretny człowiek - Kowalski, a nie sama klasa. Można upraszczając podać
generalny podział na rodzaj kodu strukturalny i obiektowy. W ujęciu strukturalnym w
celu określenia zbioru konkretnych osób należy zdefiniować zbiór (wektor, macierz)
klas (struktur), gdzie każda klasa opisuje jedną osobę. W podejściu obiektowym w
celu określenia zbioru konkretnych osób należy zainicjować zbiór obiektów tej samej
klasy. Odwołanie się do parametru klasy w podejściu strukturalnym odbędzie się
poprzez odniesie przez nazwę odpowiedniej klasy, natomiast w podejściu
obiektowym poprzez nazwę obiektu. Oznacza to, że w aplikacjach obiektowych bez
inicjacji obiektu nie można odwołać się do parametrów (pól) i metod klasy. Wyjątkiem
są te pola i metody, które oznaczone są jako statyczne (static). Pole statyczne, bez
względu na liczbę obiektów danej klasy, będzie miało tylko jedną wartość. Pola i
metody statyczne mogą być wywoływane przez referencję do klasy. Po tym
podstawowym wprowadzeniu zapoznajmy się z zasadniczą konstrukcją programu w
Javie (rozważania dotyczące Javy jako Języka obiektowego znajdują się w dalszej
części tego dokumentu).
Klasę w Javie konstruuje się zaczynając od stworzenia ramy klasy:
c l lass NazwaK l lasy {
// po l la
typ_zm i ienne j j zm i ienna;
.
.
.
typ_zm i ienne j j zm i ienna;
//konstruktor - metoda o te j j same j j nazw i ie co k l lasa - wywo ł ł ływana
//automatyczn i ie przy tworzen i iu ob i iektu dane j j k l lasy
NazwaK l lasy(typ_argumentu nazwa_argumentu){
tre ś ś ć ć_konstruktora;
1-3
Jacek Rumi ń ski - J ę zyk JAVA –
}
Jacek Rumi ń ski - J ę zyk JAVA – Rozdzia ł 1
//metody
typ_warto ś śc i i_zwracane j j nazwa_metody(typ_argumentu nazwa_argumentu){
tre ś ś ć ć_metody;
Przykład 1.1:
//RycerzJedi.java
//klasa
class RycerzJedi{
//pola
String nazwa;
String kolor_miecza;
//konstruktor
RycerzJedi(String nazwa, String kolor_miecza){
this.nazwa=nazwa;
this.kolor_miecza=kolor_miecza;
//metody
void opis(){
System.out.println(”Rycerz ”+nazwa+ ” ma ”+kolor_miecza+” miecz.”);
}
}// koniec class RycerzJedi
Warto zwrócić uwagę na zastosowaną już metodę notacji. Otóż przyjęło się w Javie
(specyfikacja języka Java) oznaczanie nazwy klasy poprzez stosowanie wielkich liter
dla pierwszej litery i tych, które rozpoczynają nowe znaczenie w nazwie klasy.
Metody i obiekty oznacza się z małych liter. Warto również stosować prosty
komentarz rozpoczynający się od znaków „//” i mający zasięg jednego wiersza. Dalej
w tekście zostaną omówione inne, ważne zagadnienia związane z konstrukcją i
opisem kodu.
Przedstawiona powyżej rama i przykład klasy nie mogą być wprost uruchomione.
Konieczne jest utworzenie elementu wywołującego określone działanie. W Javie jest
to możliwe na dwa sposoby. Po pierwsze za pomocą aplikacji, po drugie appletu.
1.2 Aplikacje
Aplikacja w języku Java to zdefiniowana klasa publiczna wraz z jedną ściśle
określoną metodą statyczną o formie:
pub l l i ic stat i ic vo i id ma i in(Str i ing args[]){
}// kon i iec pub l l i ic stat i ic vo i id ma i in(Str i ing args[])
1-4
Jacek Rumi ń ski - J ę zyk JAVA –
}
}// kon i iec c l lass NazwaK l lasy
}
Jacek Rumi ń ski - J ę zyk JAVA – Rozdzia ł 1
Tablica „args[]” będąca argumentem metody main() jest zbiorem argumentów
wywołania aplikacji w ciele której znajduje się metoda. Kolejność argumentów jest
następująca: argument 1 wywołania umieszczany jest w args[0], argument 2
wywołania umieszczany jest w args[1], itd. Występująca nazwa „args” oznacza
dynamicznie tworzony obiekt, który zawiera args.length elementów typu łańcuch
znaków. Pole „length” oznacz więc liczbę elementów tablicy. Łatwo jest więc określić
argumenty oraz ich liczbę korzystając z obiektu „args”. Warto zwrócić uwagę na to,
że oznaczenie „length” jest własnością tablicy (ukrytym polem każdej tablicy) a nie
metodą obiektu args. Istnieje metoda klasy String o nazwie „length()” (metody
zawsze są zakończone nawiasami pustymi lub przechowującymi argumenty), łatwo
więc się pomylić. Dla zapamiętania różnicy posłużmy się prostym przykładem
wywołania:
args.length - oznacz ilość elementów tablicy „args”;
args[0].length() -oznacza rozmiar zmiennej tekstowej o indeksie 0 w tablicy „args”.
Prosta aplikacja działająca w Javie będzie miała następującą formę:
Przykład 1.2:
// Jedi.java :
public class Jedi{
public static void main(String args[]){
System.out.println(”Rycerz Luke ma niebieski miecz.”);
}// koniec public static void main(String args[])
}// koniec public class Jedi
Nagrywając powyższy kod do plik „Jedi.java”, kompilując poprzez podanie polecenia:
„javac -g -verbose Jedi.java” (pamiętać należy że kompilację należy wykonać z
scieżki występowania pliku źródłowego, lub należy mieć odpowiednio ustawioną
zmienną środowiska CLASSPATH) można wykonać powstały Beta-kod „Jedi.class”
używając interpretatora: „java Jedi”. Uzyskamy następujący efekt:
Rycerz Luke ma niebieski miecz.
Jak działa aplikacja z przykładu 1.2? Otóż w ustalonej ramie klasy, w metodzie
programu uruchomiono polecenie wysłania do strumienia wyjścia (na standardowe
urządzenie wyjścia - monitor) łańcuch znaków „Rycerz Luke ma niebieski miecz.”.
Konstrukcja ta wymaga krótkiego komentarza. Słowo „System” występujące w
poleceniu wydruku oznacza statyczne odwołanie się do elementu klasy System. Tym
elementem jest pole o nazwie „out”, które stanowi zainicjowany obiekt typu
PrintStream (strumień wydruku). Jedną z metod klasy PrintStream jest metoda o
nazwie „println”, która wyświetla w formie tekstu podaną wartość argumentu oraz
powoduje przejście do nowej linii (wysyłany znak końca linii). W podanym przykładzie
nie ukazano jawnie tworzenia obiektu. Można więc powyższy przykład nieco
rozwinąć.
1-5
Jacek Rumi ń ski - J ę zyk JAVA –
Jacek Rumi ń ski - J ę zyk JAVA – Rozdzia ł 1
Przykład 1.3
// Jedi1.java :
//klasa
class RycerzJedi{
//pola
String nazwa;
String kolor_miecza;
//konstruktor
RycerzJedi(String nazwa, String kolor_miecza){
this.nazwa=nazwa;
this.kolor_miecza=kolor_miecza;
}
//metody
void opis(){
System.out.println(”Rycerz ”+nazwa+ ” ma ”+kolor_miecza+” miecz.”);
}
}// koniec class RycerzJedi
public class Jedi1{
public static void main(String args[]){
RycerzJedi luke = new RycerzJedi(”Luke”, ”niebieski”);
RycerzJedi ben = new RycerzJedi(”Obi-wan”,”biały”);
luke.opis();
ben.opis();
}// koniec public static void main(String args[])
}// koniec public class Jedi1
Zapiszmy kod aplikacji pod nazwą Jedi1.java, a następnie wykonajmy kompilację z
użyciem polecenia: „javac -g -verbose Jedi1.java”. Zwróćmy uwagę na wyświetlane w
czasie kompilacji komunikaty. Po pierwsze kompilator ładuje wykorzystywane przez
nas klasy. Klasy te znajdują się w podkatalogu „lib” katalogu „jre” (biblioteki Java
Runtime Engine). Klasy są pogrupowane w pakiety tematyczne np. „lang” czy „io”.
Wszystkie grupy klas znajdują się w jednym zbiorze o nazwie „java”. Całość jest
spakowana metodą JAR (opracowaną dla Javy) do pliku „rt.jar”. Wszystkie
prekomilowane klasy znajdujące się w pliku „rt.jar” stanowią podstawowe biblioteki
języka Java. Biblioteki te ujęte w pakiety wywoływane są następująco:
np.:
java.lang.*; - oznacza wszstkie klasy (interfejsy i wyjątki - o czym później) grupy lang,
głównej biblioteki języka Java,
java.io.*; - oznacza wszstkie klasy (interfejsy i wyjątki - o czym później) grupy io
(wejście/wyjście), głównej biblioteki języka Java,
java.net.Socket; - oznacza klasę Socket grupy net (sieć), głównej biblioteki języka
Java.
Wykorzystując różne klasy biblioteki języka Java należy pamiętać w jakim pakiecie
się znajdują. Wszystkie klasy poza tymi zawartymi w pakiecie „java.lang.*”
1-6
Jacek Rumi ń ski - J ę zyk JAVA –
Jacek Rumi ń ski - J ę zyk JAVA – Rozdzia ł 1
wymagają zastosowania jawnego importu pakietu (klasy) w kodzie programu.
Odbywa się to poprzez dodanie na początku kodu źródłowego linii:
np.:
i import j java.net.*;
Po dodaniu takiej linii kompilator wie gdzie szukać używanych w kodzie klas. Pakiety
zaczynające się od słowa „java” oznaczają zasadnicze pakiety języka Java. Niemniej
możliwe są różne inne pakiety, których klasy można stosować np.:
„org.omg.CORBA”. Nazewnictwo pakietów jest określone w specyfikacji języka i
opiera się o domeny Internetowe. Oczywiście można tworzyć własne pakiety.
Występujące w nazwie pakietu kropki oznaczają zmianę poziomu w drzewie
katalogów przechowywania klas. Przykładowo „org.omg.CORBA.Context” oznacza,
że w katalogu „org”, w podkatalogu „omg”, w podkatalogu „CORBA” znajduje się
klasa „Context.class”; czyli zapis pakietu jest równoważny w sensie systemu plików:
/org/omg/CORBA/Context.class.
Obserwując dalej komunikaty wyprodukowane przez kompilator Javy łatwo
zauważyć, że zapisane zostały dwie klasy: RycerzJedi.class oraz Jedi1.class.
Oddzielnie definiowane klasy zawsze będą oddzielnie zapisywane w Beta-kodzie.
Po kompilacji należy uruchomić przykład 1.3. W tym celu wywołajmy interpretator:
„java Jedi1”. Zdarza się czasem, że wykorzystywany Beta-kod klas pomocniczych
(np. klasa RycerzJedi.class) znajduje się w innym miejscu dysku. Wówczas
otrzymamy w czasie wywołania aplikacji błąd o niezdefiniowanej klasie. Należy wtedy
ustawić odpowiednio zmienną środowiska CLASSPATH lub wywołać odpowiednio
interpretator:
„java -cp <ścieżka dostępu do klas> NAZWA_KLASY_GŁÓWNEJ”.
Prawidłowe działanie aplikacji z przykładu 1.3 da następujący rezultat:
Rycerz Luke ma niebieski miecz.
Rycerz Obi-wan ma biały miecz.
Prześledźmy konstrukcję kodu źródłowego w przykładzie 1.3. Kod składa się z
dwóch klas: RycerzJedi i Jedi1. Klasa RyczerzJedi nie posiada metody main, a więc
nie jest główną klasą aplikacji. Klasa ta jest wykorzystywana dla celów danej aplikacji
i jest skonstruowana z pól, konstruktora i metody. Pola oznaczają pewną własność
obiektów jakie będą tworzone: nazwa - łańcuch znaków oznaczający nazwę rycerza
Jedi; kolor_miecza - łańcuch znaków oznaczający kolor miecza świetlnego rycerza
Jedi. Konstruktor jest metodą wywoływaną automatycznie przy tworzeniu obiektu.
Stosuje się go do podawania argumentów obiektowi, oraz do potrzebnej z punktu
widzenia danej klasy grupy operacji startowych. Wywołanie konstruktora powoduje
zwrócenie referencji do obiektu danej klasy. Nie można więc deklarować konstruktora
z typem void. W rozpatrywanym przykładzie konstruktor posiada dwa argumenty o
nazwach takich samych jak nazwy pól. Oczywiście nie jest konieczne stosowanie
takich samych oznaczeń. Jednak w celach edukacyjnych zastosowano tu te same
oznaczenia, żeby pokazać rolę słowa kluczowego „this”. Słowo „this” oznacza obiekt
klasy w ciele której pojawia się „this”. Stworzenie więc przypisania this.nazwa=nazwa
powoduje przypisanie zmiennej lokalnej „nazwa” do pola danej klasy „nazwa”. Klasa
RycerzJedi ma również zdefiniowaną metodę opis, która wyświetla własności obiektu
1-7
Jacek Rumi ń ski - J ę zyk JAVA –
Zgłoś jeśli naruszono regulamin