Interfejsy
Interfejsy wyłącznie definiują zestaw metod i ewentualnie stałe atrybuty klasy, lecz niczego nie implementują. Interfejsy to szablony klas, które ułatwiają organizowanie elementów świata obiektowego. W interfejsie określone są wyłącznie: nazwy metod, typ zwracanych danych, zestaw parametrów każdej metody, a nie występuje żaden kod. Takie "puste" definicje metod nazywamy sygnaturami metod. Kod tych metod musi być zaimplementowany w klasach implementujących dany interfejs.
public interface DivingAnimal {
int JAKAŚ_STAŁA = 1001; // w interfejsie można deklarować wyłącznie stałe, które muszą być zainicjowane
// przy użyciu określonej wartości
void dive( int depth );
}
public interface FlyingAnimal {
void fly( int periodOfTime );
}
Jeśli klasa Perkoz implementuje interfejs DivingAnimal jest opisana w następujący sposób:
public class Perkoz implements DivingAnimal {
...
void dive( int targetDepth ) {
//tutaj implementacja procesu nurkowania na określoną głębokość
}
}
Użycie interfejsów pozwala na polimorfizm (wielopostaciowość) klas, poniważ jedna klasa może implementować wiele interfejsów:
public class Perkoz implements DivingAnimal, FlyingAnimal{
...
void dive( int targetDepth ) {
//tutaj implementacja procesu nurkowania na określoną głębokość
}
void fly( int periodOfTime ) {
//tutaj implementacja procesu latania przez określony czas
}
}
Jeśli klasa implementuje interfejs, wszystkie zadeklarowane w interfejsie metody muszą występować w tej klasie i muszą zawierać konkretną implementację. Jednakże implementacja tych metod może być różna w różnych klasach implementujących dany interfejs.
Wszystkie metody interfejsu są domyślnie publiczne i abstrakcyjne - nie trzeba dodawać słów kluczowych public i abstract.
W interfejsie możemy definiować wyłącznie atrybuty typu public static final - czyli wyłącznie STAŁE. Wszystkie stałe muszą być zainicjowane przy użyciu określonej wartości. Również nie trzeba dodawać tych słów kluczowych przed atrybutami.
Interfejs może dziedziczyć od innych interfejsów - także od kilku, co w wypadku klas jest zabronione - klasa może dziedziczyć wyłącznie od jednej klasy.
public interface EggBearingAnimal {
void bearEgg();
}
public interface CrawlingAnimal {
void crawl();
}
public interface Reptile extends EggBearingAnimal, CrawlingAnimal {
void hunt();
}
public class Crocodile implements Reptile {
public void bearEgg() {
...[ implementacja_metody ]...
}
public void crawl() {
...[ implementacja_metody ]...
}
public void hunt() {
...[ implementacja_metody ]...
}
}
Metody interfejsu nie mogą być zadeklarowane jako statyczne.
Interfejsy jako typy danych
Interfejs można wykorzystać jako "ogólniejszy" typ klasy. Jeśli przyjmiemy, że oprócz klasy Perkoz istnieje następująca klasa Nietoperz:
public class Nietoperz implements FlyingAnimal {
...
}
...wówczas w innym miejscu kodu możemy użyć następującej konstrukcji:
...
FlyingAnimal perkoz = new Perkoz();
FlyingAnimal nietoperz = new Nietoperz();
...