Obsah
Abstraktní třída je tak označena v hlavičce, např.:
public abstract class AbstraktniChovatel
...
Obvykle má alespoň jednu abstraktní metodu, deklarovanou např.:
public abstract void vypisInfo();
Od abstraktní třídy nelze vytvořit instanci, nelze napsat např.:
Viz Svět chovatelství z učebnice:
rozhraní svet.chovatelstvi.Chovatel
-
specifikace, co má chovatel umět
svet.chovatelstvi.AbstraktniChovatel
-
částečná implementace chovatele
svet.chovatelstvi.psi.ChovatelPsu
- úplná
implementace chovatele psů
Pozn.: Obecný chovatel se ihned úplně implementovat nedá (ještě to neumíme), proto je definován jako abstraktní třída AbstraktniChovatel a teprve až ChovatelPsu je neabstraktní třída.
Viz demo searching
pro BlueJ:
Rozhraní - specifikuje, co má prohledávač umět
public interface Searcher {
/**Nastav do vyhledávače pole, kde se bude vyhledávat */
void set(double[] a);
/** Zjisti, zda pole obsahuje číslo d */
boolean contains(double d);
/**Zjisti pozici, na níž je v poli číslo d.
Není-li tam, vrať -1 */
int indexOf(double d);
}
Abstraktní třída - předek konkrétních plných implementací prohledávače
public abstract class AbstractSearcher implements Searcher { // implementuje, ale ne úplně
// úložiště prvků JE implementováno
protected double[] array;
// nastavení úložiště prvků JE implementováno
public void set(double[] a) {
array = a;
}
// rozhodnutí, zda prvek je přítomen na základě vyhledání jeho pozice
public boolean contains(double d) {
return indexOf(d) >= 0;
}
// samotné vyhledání prvku není implementováno
public abstract int indexOf(double d);
}
Konkrétní třída - plná implementace prohledávače - tentokrát pomocí lineárního prohledání
public class LinearSearcher extends AbstractSearcher { // doimplementuje se, co zbývá
// a to je metoda indexOf!
public int indexOf(double d) {
for(int i = 0; i < array.length; i++) {
if(array[i] == d) {
return i;
}
}
return -1;
}
}
Podobně jako u tříd, i rozhraní mohou být rozšiřována/specializována. Mohou dědit.
Na rozdíl od třídy, která dědí maximálně z jedné nadtřídy (předka) -
z rozhraní můžeme odvozovat potomky (podrozhraní - subinterfaces)
dokonce i vícenásobně - z více rozhraní odvodíme společného potomka slučujícího a rozšiřujícího vlastnosti všech předků.
Přesto to nepřináší problémy jako u klasické plné vícenásobné dědičnosti např. v C++, protože rozhraní samo
Příklad - Informing informuje „jen trochu“, WellInforming je schopen ke standardním informacím (writeInfo) přidat dodatečné informace (writeAdditionalInfo).
public interface Informing {
void writeInfo();
}
public interface WellInforming extends Informing {
void writeAdditionalInfo();
}
Třída, která chce implementovat intf.DobreInformujici, musí implementovatoběmetody předepsané tímto rozhraním. Např.:
public class Informator implements WellInforming {
public void writeInfo() {
... // kód metody
}
public void writeAdditionalInfo() {
... // kód metody
}
}
Používají se i prázdná rozhraní - nepředepisující žádnou metodu
deklarace, že třída implementuje také rozhraní, ji "k ničemu nezavazuje", ale poskytuje typovou informaci o dané třídě
i v Java Core API jsou taková rozhraní - např.
java.lang.Cloneable