public interface Informing { String retrieveInfo(); }
public interface Screaming { String scream(); }
public class Person implements Informing, Screaming {
public String retrieveInfo() { ... }
public String scream() { ... }
}
Tomáš Pitner, Radek Ošlejšek, Marek Šabo
Jedna třída může implementovat více rozhraní.
Jednoduše v případě, kdy objekty dané třídy toho "mají hodně umět".
Příklad: Třída Person
implementuje 2 rozhraní:
public interface Informing { String retrieveInfo(); }
public interface Screaming { String scream(); }
public class Person implements Informing, Screaming {
public String retrieveInfo() { ... }
public String scream() { ... }
}
Co kdyby obě rozhraní měla stejnou metodu?
public interface Informing { String retrieveInfo(); }
public interface Screaming { String retrieveInfo(); }
Mají-li úplně stejnou hlavičku, je to v pořádku:
public class Person implements Informing, Screaming {
@Override
public String retrieveInfo() { ... }
}
Mají-li stejný název i parametry, ale různý návratový typ, je to PROBLÉM.
public interface Informing { String retrieveInfo(); }
public interface Screaming { void retrieveInfo(); }
public class Person implements Informing, Screaming { ... }
To samozřejmě nelze — viz totéž u přetěžování metod:
Person p = new Person();
// do we call method returning void or
// string and we ignore the result?
p.retrieveInfo();
Nesnesou se tedy metody lišící se pouze návratovým typem. |
Metody i samotné rozhraní by mělo obsahovat kvalitní dokumentaci s detailním popisem.
Rozhraní je jako vtip. Když ho třeba vysvělovat, není tak dobré.
Občas se kupodivu používají i prázdná rozhraní, nepředepisující žádnou metodu.
Úplně bezúčelné to není — deklarace, že třída implementuje určité rozhraní, poskytuje typovou informaci o dané třídě.
Např. java.lang.Cloneable
, java.io.Serializable
.
Rozhraní může převzít (můžeme říci též dědit) metody z existujících rozhraní.
Říkáme, že rozhraní mohou být rozšiřována (extended).
Rozšířené rozhraní by mělo nabízet něco navíc než to výchozí (rozšiřované).
Příklad: Každá třída implementující WellInforming
musí pak implementovat i metody z rozhraní Informing
:
interface Informing {
String retrieveInfo();
}
interface WellInforming extends Informing {
String detailedInfo();
}
public class Person implements WellInforming {
public String retrieveInfo() { ... }
public String detailedInfo() { ... }
}
implements
a kde extends
Ztrácíte se v klíčových slovech?
implements
= třída implementuje rozhraní
ve třídě musím napsat kód (obsah) metod předepsaných rozhraním
extends
= když dědím ze třídy nebo rozšiřuji rozhraní
dědím metody automaticky
Rozhraní může dědit z více rozhraní zároveň:
public interface Informing { String retrieveInfo(); }
public interface Screaming { String scream(); }
public interface WellInforming extends Informing, Screaming {
String detailedInfo();
}
Každá třída implementující WellInforming
musí implementovat všechny 3 metody.
Dědičnost můžeme řetězit:
public interface Grandparent { int method1(); }
public interface Parent extends Grandparent { int method2(); }
public interface Child extends Parent { int method3(); }
Grandparent
pak obsahuje jednu metodu, Parent
dvě, Child
tři.
Úplně stejné metody ze dvou rozhraní jsou OK
public interface A {
void someMethod();
}
public interface B {
void someMethod();
}
public interface AB extends A, B {
// it is OK, methods have same signature
}
Stejné metody s různými parametry ze dvou rozhraní jsou také OK
public interface A {
void someMethod();
}
public interface B {
void someMethod(int param);
}
public interface AB extends A, B {
// it is OK, methods have different params
}
Dvě metody lišící se jen návratovým typem nejsou OK
Třída implementující rozhraní AB
by musela mít dvě metody
lišící se jen návratovým typem, a to nejde
public interface A {
void someMethod();
}
public interface B {
int someMethod();
}
public interface AB extends A, B {
// cannot be compiled
}