AbstractWcześniej omówiłem modyfikator dostępu w składowych klas. Jednak to nie są wszystkie modyfikatory, jakie mogą być użyte wobec metod i zmiennych. Modyfikatory “abstract” i “final” zostały już wcześniej omówione ,ale wciąż nie są to wszystkie modyfikatory.
Do omówienia zostały słowa kluczowe jak:“transient”,”synchronized”,”native”,”strictfp” i “static” (na inny wpis).
Najpierw pokażę słowa kluczowe, które odwołują się zmiennych, jak i do metod. W innym wpisie pokażę jakie zachowanie deklaruje słowo “static” w metodzie i przy zmiennej.
Finale Metody
Słowo kluczowe “final” zabezpiecza metodę przed nadpisaniem przez klasę pochodną. Jak pamiętasz klasy zadeklarowane ze słowem final nie mogły być klasami bazowymi. Pisałem ,że to zachowanie ma zastosowanie tylko w szczególnych przypadkach. Jeśli nie istnieje konkretny powód zabezpieczenia klasy nie powinno się tego robić.
Sprawa jest podobna z finalnymi metodami, to zachowanie trzeba też użyć mądrze. W końcu, jeśli metoda nie może być nadpisana to znaczy ,że jej działanie nie może być już dalej rozszerzane poprzez polimorfizm.
Deklaracja metody final wygląda tak:
public class SuperKlasa
{
public final void ostatecznaMetoda()
{
System.out.print("Moja ostatnia wersja");
}
}
Super klasa może być użyta jako klasa bazowa ,w końcu nie ma ona słowa final. Jednak próba nadpisania metody ze słowem final skończy się niepowodzeniem.
Finale argumenty
Argumenty w metodzie są to zadeklarowane zmienne w nawiasach okrągłych, w definicji metody. Typowa deklaracja metody wygląda tak:
public String getNamesOfGames(int year, int disks) {}
Argumenty metody są w pewnym sensie zmiennymi lokalnymi. Co oznacza ,że do argumentów też można użyć słowa kluczowego “final”.
public String getNamesOfGames(int final year,final int disks) {}
W tym przykładzie oba argumenty zostały zadeklarowane jako final. Oznacza to ,że ich wartość nie może być zmieniona wewnątrz metody, czyli nie można do tych zmiennych przypisać innej wartości.
Deklarując metodę z finalnym argumentem sprawiasz ,że on wewnątrz metody nigdy nie ulegnie zmianie. Wartość argumentu, która została przesłana do tej metody nigdy się nie zmieni.
Abstrakcyjne metody
Abstrakcyjna metoda jest to metoda, która nie ma ciała, czyli jest zadeklarowana ,ale nie zaimplementowana. Ta metoda zamiast nawiasów klamrowych używa po sygnaturze metody myślnika “;”. Abstrakcyjne metody są dopiero implementowane wewnątrz klas pochodnych jednak one muszą przestrzegać jej sygnatury.
Przykładowo w klasie abstrakcyjnej “Ssak” zadeklarowałeś metodę abstrakcyjną “SenRem()”. Umożliwiając w ten sposób każdej klasie pochodnej na implementacje tej metody zgodnie z pewnymi zasadami,
public abstract void senRem();
Warto też zapamiętać ,że metoda abstrakcyjna może być użyta tylko w klasie abstrakcyjnej.
Jednak tak jak opisałem to wcześniej klasa abstrakcyjna może posiadać inne zwykłe metody.
public abstract class PochodnaKlasa extends SuperKlasa
{
public abstract void senRem();
public void paznokcie(){;};
}
Jak widzisz metoda paznokcie() nie jest metodą abstrakcyjną i łatwo to zauważyć, ponieważ:
- Nie ma słowa kluczowego abstract
- Metoda ma nawiasy klamrowe
- Metoda ta posiada ciało. Chociaż w tym wypadku jest to tylko myślnik.
Każda klasa, która dziedziczy po klasie abstrakcyjnej musi implementować metodę abstrakcyjną chyba ,że jest ona też klasą abstrakcyjną.
public abstract class PochPochKlasa extends PochodnaKlasa
{
//OK
}
Jednak jeśli tak nie jest musi ona zaimplementować metody abstrakcyjne.
public class PochPochKlasa extends PochodnaKlasa
{
@Override public void senRem()
{
// TODO Auto-generated method stub
}
}
public class PochPochKlasa extends PochodnaKlasa
{
@Override public void senRem()
{
// TODO Auto-generated method stub
}
}
Warto o tym pamiętać.
Do utrwalenia tej wiadomości przyda się lepszy i czytelniejszy przykład wraz z ładnym diagramem.Oto przykład drzewa dziedziczenia, w którym udział biorą dwie klasy abstrakcyjne i jedna zwykła klasa.
public abstract class Device
{
private String type;
public abstract void turnOn();
//abstrakcyjna metoda
public String getType()
{
//zwykła metoda
return type;
}
}
public abstract class Computer extends Device
{
public abstract void turnOn();
//wciąż jest to metoda abstrakcyjna
public void computerExecute()
{
//hipotetyczny kod
}
public abstract class CellPhone extends Device
{
@Override public void turnOn()
{
// TODO Auto-generated method stub
}
}
Jak wiele metod ma klasa Amiga? Ma ich aż trzy w końcu klasa ta odziedziczyła też metody publiczne “computerExecute” i “getType”. Jak widzisz metoda “turnOn” jest wciąż abstrakcyjna w klasie Computer jest to możliwe ponieważ ta klasa jest też abstrakcyjna.
Klasa Amiga już nie może tego zrobić, ponieważ nie jest abstrakcyjna. Klasa abstrakcyjna CellPhone może implementować metodę abstrakcyjną i w sumie to chciałem wykazać w tym przykładzie.
W czasie implementacji metody abstrakcyjnej jej sygnatura musi się dokładnie zgadzać. W przeciwnym wypadku kompilator zwróci błąd, ponieważ w rzeczywistości metoda abstrakcyjna wciąż nie jest zaimplementowana.
public abstract class A
{
abstract void a();
}
Kod powyżej stworzył tylko metodę przeciążoną ‘a’. Metoda abstrakcyjna wciąż nie jest zaimplementowana.
Metoda nigdy przenigdy nie może być oznaczona jako abstract i final oraz private i abstract.
Abstrakcyjne metody muszą być zaimplementowane przez klasy pochodne co znaczy ,że muszą być w jakiś sposób dostępne ,a słowa kluczowe jak final i private blokują tę możliwość. Oczywiście słowo final może być użyte na końcu drzewa dziedziczenia, gdzie metoda abstrakcyjna została już dawno zaimplantowana.
Modyfikator abstract też nie może być mieszany ze słowem static. Jest całkowicie logiczne ,ale ponieważ nie objaśniłem tego słowa, to jeszcze powiem tylko, że jest to nielegalne.
Synchronized Metody
Synchronized indykuje ,że do tej metody można uzyskać dostęp tylko w jednym wątku. Wątkowość to tematyka na inną okazję dlatego na razie omówię jak ten modyfikator wygląda dla metody. Słowo kluczowe synchronized nie może być odniesione do klas czy zmiennych, używa się go tylko do metod.
public synchronized String getNamesOfGames(int year, int disks) {}
Synchronized może być użyty w każdym poziomie dostępu (public, default, private, protected).
Native Metody
Modyfikator “Native” oznacza metodę, która jest zaimplementowana w kodzie, który się nazywa “Platform-dependent code” (kod natywny) zazwyczaj jest to język “C”.
Na szczęście użycie tego słowa kluczowego nie jest wymagane na egzaminie. Co trzeba wiedzieć to to ,że jest to modyfikator (słowo kluczowe) oraz odnosi się on tylko do metod.
Ciała metod natywnych kończą się myślnikiem tak jak w metodach abstrakcyjnych nie ma tutaj nawiasów klamrowych.
Strictfp Metody
Pisałem o tym wcześniej, ponieważ ten modyfikator może być użyty także do klas. Nie musisz wiedzieć co ten modyfikator robi. Jedyne co trzeba wiedzieć to to ,że jest to modyfikator, który działa dla metod i klas ,ale nie zmiennych.
Opis działania Strictfp z angielskiej wiki.
To tyle na razie:
Następnym razem omówię deklarację zmiennych. A potem typy wyliczeniowy w Javie.