Wenn ich ein Interface A habe, eine abstrakte Klasse B, die A implementiert und und eine normale Klasse C, die B erweitert, dann implementiert natürlich auch C das Interface A:
public interface A { ... } public abstract class B implements A { ... }
besser wäre, nicht von B zu erben, sonder B als Abhängigkeit in C zu injizieren:
class C implements A {
private final B commonBehavior;
C(B commonBehavior){ this commonBehavior = commonBehavior;}
void methodFromA() { commonBehavior.methodFromA();}
}```
Leider kennt Java keine kürzere Schreibweise für solche Delegationen.
Das Mehr an Code bring viel Flexibilität, nicht zuletzt für die UnitTests...
bye
TT
Es geht an dieser Stelle darum, zwei “Geschmacksrichtungen”, die das Standardverhalten von B (die Klasse heißt bei mir auch Standard…) leicht abwandeln. C (und D) sind relativ kleine Klassen. C (und D) nutzen große Teile von B und überschreiben keineswegs alle Methoden, sondern nur exakt die kleinstmöglichen Stellen, an denen ihr Verhalten eben abweicht.
Daher denke ich, dass an dieser Stelle die Vererbung wirklich Sinn macht. Ansonsten bevorzuge ich ebenfalls “has a” gegenüber “is a”.
kürzer und üblich dürfte Verzicht auf Wiederholung des Interfaces sein,
gibt auch Eclipse-Warnung:
‘Redundant superinterface A for the type C, already defined by B’
man stelle sich vor man würde bei jedem geerbten JPanel die Interface wie Accessible, Serializable, TransferHandler.HasGetTransferHandler, ImageObserver, MenuContainer aufzählen…,
zumal manche ja auch oben gar nicht mehr sichtbar
allerdings steht auch in der API: public abstract class Component implements ImageObserver, MenuContainer, Serializable
+ public abstract class JComponent extends Container implements Serializable, TransferHandler.HasGetTransferHandler
Serializable kommt also zweimal in der Hierarchie vor,
wenn man darauf Wert legt, wichtiges was nicht vergessen werden soll, aus Doku-Zwecken, wenn man die Warnungen passend eingestellt hat,
dann kann man das auch gut wiederholen
Wie ich vor 9 Jahren schon an anderer Stelle geschrieben habe
Eine allgemeine Stilfrage: Wenn eine Klasse von einer anderen Klasse erbt, die ein bestimmtes Interface implementiert, sollte man dann nochmal angeben, dass das interface implementiert wird?
…
Das „implements“ dazuzuschreiben wird irgendwie so redundant. Es wegzulassen wirkt irgendwie unvollständig.
Man könnte da noch „Zwischenstufen“ unterscheiden:
interface A { void foo(); }
class B implements A {
@Override
public void foo() { ... }
}
// Hier nicht hinschreiben, obwohl man es könnte
class C0 extends B {
}
// Hier nochmal hinschreiben, weil man es ja "echt" SELBST implementiert
class C1 extends B implements A {
@Override
public void foo() { ... }
}
Aber das ist natürlich nicht klar abgrenzbar (spätestens wenn im Interface zwei Methoden stehen ;-)).
Eine Argumentationsschiene könnte sein, ob man explizit die Zusicherung machen will: Man könnte das implements nochmal hinschreiben, wenn man explizit sagen will, dass man das Interface „absichtlich“ (vertraglich zugesichert) implementiert, und es nicht etwa nur „zufällig, versehentlich“ von der Elternklasse geerbt hat.
Relevant wird das ganze IMHO sowieso nur in speziellen Zusammenhängen - vielleicht wenn man von einer package-privaten Klasse erbt, die das Interface implementiert. Diese Klasse könnte (weil sie ja nicht public ist) irgendwann so geändert werden, dass sie das Interface nicht mehr implementiert. Aber selbst da macht es technisch gesehen keinen Unterschied, ob man es hinschreibt oder nicht…