Zasady tworzenia i wykorzystywania klas:
• Program jest zbiorem klas.
• Wszystkie klasy dziedziczą z klasy Object Javy, nawet, gdy nie zaznaczono tego w definicji klasy:
class Klasa
{ ………… }
• Domyślnie, klasy są zawsze dostępne dla wszystkich innych klas zawartych w tym samym pakiecie.
• Aby klasa była dostępna w różnych pakietach, musi zostać zadeklarowana jako publiczna.
• W pliku źródłowym może wystąpić tylko jedna klasa publiczna o nazwie identycznej z nazwą pliku.
• Obiekty klas po zadeklarowaniu muszą zostać utworzone za pomocą operatora new z konstruktorem klasy (lub za pomocą inicjatora).
• Obliczenia w klasie rozpoczynają się (jeśli jest) od statycznego wyrażenia (bloku) inicjującego:
static { // deklaracje i instrukcje
}
Definicja każdej klasy zbudowana jest w następujący sposób:
[ModyfikatorKlasy] class NazwaKlasy
[extends NadKlasa] [implements Interfejsy]
{
/* definicje metod i pól */
}
ModyfikatorKlasy może być kombinacją następujących wyrażeń: abstract -
Definiuje klasę abstrakcyjną zawierającą tylko metody abstrakcyjne (niezaimplementowane). Nie jest możliwe utworzenie żadnych obiektów tej klasy; jest ona użyteczna jedynie podczas budowania hierarchii klas (przy
dziedziczeniu). Klasa abstrakcyjna stanowi wzór do tworzenia klas pochodnych, jest więc szablonem do tworzenia innych klas.
final -
Od klasy tego typu niemożliwe jest utworzenie klas pochodnych. Klasy takie stosuje się w celu zapewnienia odpowiedniego poziomu bezpieczeństwa aplikacjom oraz niekiedy do oznaczenia klas, nad którymi prace zostały ukończone - wiernie odwzorowujących obiekty
rzeczywistości.
public -
Taka klasa jest udostępniana na zewnątrz pakietu ( package), w którym się znajduje. W jednym pliku może wystąpić tylko jedna klasa tak zadeklarowana. W przypadku użycia jej poza pakietem, w którym się znajduje, należy użyć odwołania:
"<NazwaKlasy>.java".
private -
Klasa private dostępna jest wyłącznie wewnątrz danego pakietu (względnie pliku). Jeśli w definicji klasy nie zostanie wpisany żaden modyfikator zostaje ona automatycznie uznana za klasę private
synchronizable - Java, dzięki mechanizmowi wątków ( threads), umożliwia tworzenie programów obsługujących prawdziwą
wielozadaniowość. Używanie w tego typu programach
wspólnych obszarów danych względnie odwołań do tych samych funkcji łatwo może prowadzić do zakleszczenia programu ( deadlock) bądź do powstania błędów wartości.
Aby tego uniknąć Java umożliwia synchronizację wątków.
Czasem może okazać się przydatne przekazanie obiektów jako parametrów funkcji. Staje się możliwe tylko i wyłącznie wtedy, gdy klasa przekazywanego obiektu zostanie
zdefiniowana jako synchronizable.
Składnia deklaracji metod jest bardzo podobna do składni deklaracji funkcji w języku C++:
ModyfikatorMetody TypZwracanejWartości Nazwa
(Typ Argument1, Typ Argument2, ...)
{
/* implementacja (kod źródłowy) metody */
}
ModyfikatorMetody może być jednym z następujących wyrażeń: public -
Metoda dostępna dla innych metod spoza jej klasy.
protected -
Metoda może być używana przez metody swojej klasy oraz metody jej wszystkich klas potomnych.
private -
Dostęp do metody mają tylko inne metody tej samej klasy.
<puste> -
Metoda dostępna dla metod tych klas, które są zgrupowane w tym samym pakiecie.
final -
Dziedziczenie pozwala klasom pochodnym implementować na nowo dziedziczone metody - dziedziczona metoda zostaje przesłonięta przez nową implementację. Modyfikator final powoduje, że takie przesłanianie nie jest możliwe . Metody z modyfikatorem final są rozwijane „inline” i nie są wirtualne.
static -
Do wywołania „normalnej" metody potrzebny jest zawsze obiekt (ponieważ wywołuje się metodę obiektu, a nie klasy). Metody zdefiniowane jako static są wspólne dla wszystkich obiektów danej klasy. Należą do klasy, a nie do obiektu. Jako statyczne mogą być definiowane także pola danych. Są one użyteczne, kiedy istnieje potrzeba zapisania wspólnych dla wszystkich egzemplarzy klas danych.
synchronized -
Metoda zdefiniowana jako synchronized na początku wykonywania zablokuje dostęp do obiektu, do którego należy i odblokuje go, gdy zakończy działanie. Jeśli dostęp do obiektu już wcześniej został zablokowany, to metoda taka oczekuje na odblokowanie obiektu zanim zacznie się wykonywać.
Mechanizm ten ma bardzo istotne znaczenie w przypadku programów wielowątkowych.
native -
Modyfikator native służy do oznaczania danej funkcji jako implementowanej z wykorzystaniem nieprzenośnych cech danej platformy.
ModyfikatorPola TypPola NazwaPola
- do definiowania pół klasy można użyć tych samych modyfikatorów, jakich do definiowania pól klasy, w szczególności:
• pola zdefiniowane jako publiczne (public) mogą podlegać modyfikacjom dokonywanym z zewnątrz
• pola zdefiniowane jako private dostępne są tylko dla metod własnej klasy
• dostęp do pól protected dozwolony jest dodatkowo dla metod klas pochodnych
• pola zadeklarowane bez modyfikatora static są polami (zmiennymi) obiektu, pola statyczne są polami (zmiennymi) klasy: o pola obiektu są dostępne z poziomu obiektu: obiekt.pole, są tworzone w momencie tworzenia obiektu i inicjowane na domyślne wartości odpowiedniego typu (chyba, że są inicjowane jawnie) o pola klasy są dostępne z poziomu klasy, są tworzone w momencie ładowania klasy i odpowiednio inicjowane
• pola oznaczone modyfikatorem final nie mogą podlegać modyfikacjom, są odpowiednikiem stałych
• wszystkie metody są definiowane w treści klas
• domyślnie wszystkie metody są wirtualne
• jeśli metoda zwraca obiekt odpowiedniej klasy, to można bezpośrednio dopisać kolejne wywołanie metody:
wynik = obiekt.Metoda1().Metoda2();
• parametry:
o parametry typów prostych są przekazywane przez wartość o obiekty są przekazywane przez referencję; nawet kiedy obiekt zostaje w metodzie zmieniony na inny, to jest to widoczne jedynie w treści tej metody (nowy obiekt jest obiektem lokalnym): void Test( Klasa ob2 )
{ ob2. = new Klasa();
ob2.pole = W2;
}
……
ob1 = new Klasa();
ob1.pole = W1;
Test( ob1 );
// ob1.pole == W1
• metody mogą być przeciążane: muszą się różnić liczbą lub/i typami parametrów
• w każdej metodzie niestatycznej jest dostępny obiekt, na rzecz którego ta metoda została wywołana, w postaci zmiennej this
• konstruktor jest metodą wykonywaną w momencie tworzenia obiektu
• jeśli nie zdefiniowano jawnie konstruktora, to jest tworzony bezparametrowy konstruktor domyślny (wywołujący konstruktor klasy nadrzędnej)
• nazwa konstruktora jest identyczna z nazwą klasy
• konstruktory można przeciążać
• każdy konstruktor powinien w pierwszej kolejności wywoływać konstruktor klasy nadrzędnej (za pomocą metody super())
Interfejsy pozwalają na dziedziczenie wielokrotne (wielobazowe), niedozwolone na poziomie klas. Interfejs jest abstarakcyjną klasą, która zawiera jedynie statyczne pola danych oraz deklaracje metod:
[public] interface NazwaInterfejsu
[extends Interfejs1, Interfejs2, ...]
{
// abstrakcyjne metody i statyczne pola danych
}
• Interfejs pozwala dokładnie określić metody, które muszą zostać zaimplementowane, aby wykonać postawione przed nim zadanie.
• Szczegóły implementacji nie są w tym miejscu istotne.
• Implementacja metod interfejsu odbywa się dopiero w klasie, która z niego bezpośrednio korzysta.