Checkstyle: Wann ist eine Methode für Vererbung entworfen?

Lowpass

Aktives Mitglied
Zur Zeit lasse ich meinen Code durch Checkstyle prüfen und erhalte bei (fast?) allen Methoden die Meldung, dass diese nicht für Vererbung entworfen worden ist und darum als final deklariert werden soll.

Nun frage ich mich: ab wann ist denn eine Methode für Vererbung entworfen? bzw. anders gefragt: wie deklariert man eine Methode korrekt für Vererbung?

...oder interessiert sich Checkstyle am Ende nur dafür, ob es bereits konkrete Klassen gibt, die von der aktuellen Klasse ableiten und die in Frage kommende Methode bereits überschreiben?
 

Marco13

Top Contributor
Ich kenne die konkrete Meldung von CheckStyle nicht, aber rein theoretisch-formal und bei (übertrieben?) konsequenter Auslegung des Open/closed principle - Wikipedia, the free encyclopedia könnte man sagen: Alles, was final sein kann, sollte final sein. D.h. wenn man eine Methode definiert, die nicht überschrieben werden soll, dann "sollte" man die schreiben als
Code:
final void method(final int a, final Object b, final String c) { ... }

Konkret steht dazu ja auch hier was: Checkstyle - Class Design...
 

Lowpass

Aktives Mitglied
Es ist mir klar was zu tun ist, wenn eine Methode nicht für Vererbung entworfen ist - aber die Frage ist ja genau das Gegenteil: wann ist eine Methode für Vererbung entworfen?

Allerdings hilft da Dein Link (danke dafür):
The exact rule is that nonprivate, nonstatic methods of classes that can be subclassed must either be
- abstract or
- final or
- have an empty implementation

Finde ich allerdings ganz schön krass - und mir zudem nicht verständlich:

Denn dann wäre Object.toString ebenfalls nicht für Vererbung entworfen und Checkstyle würde warnen? toString ist weder abstract, noch final, noch leer - und ist absolut für Vererbung entworfen.
 
M

maki

Gast
Finde ich auch "krass", aber vor allem unpräzise.
Manchmal will man eben eine Default-Implementierung bereitstellen... denke dass diese Regeln nicht wirklich zu eng zu sehen sind, sondern der Tatsache, dass die meisten OO Sprachen kein Sprachkonstrukt haben welches aussagt, das etwas überschrieben werden, kann, aber nicht muss.
 

fastjack

Top Contributor
Whl. muß die default-Implementierung dann in eine Default-Klasse, in der sie dann final ist. Ich denke eher, das ist Checkstyle-Logik.
 
Zuletzt bearbeitet:
M

maki

Gast
Whl. muß die default-Implementierung dann in eine Default-Klasse, in der sie dann final ist.
Meinst du final Methoden?
Die sind dann nicht nur default, sondern auch nicht überschreibbar ;)

Das Problem ist mE dass man nur sagen kann, dass etwas nicht überschrieben werden kann (final), oder aber, dass etwas überschrieben werden muss (abstract, dann geht es aber nicht mehr um das Überschreiben sondern um das implementieren), aber nicht, das etwas überschrieben werden kann, aber nicht muss.
 

Lowpass

Aktives Mitglied
Klar kann man Checkstyle umkonfigurieren und ich schrecke auch nicht davor zurück, das zu tun - nur würde ich eben vorher gern wissen, was sich die Väter der Default-Konfiguration dabei überlegt haben.

Checkstyle meckert per default auch, wenn man abstrakte Klassen definiert. Es heisst dann, man soll besser ein Interface daraus machen - da bin ich aber gänzlich anderer Meinung. Ein Interface kann von jeder beliebigen Klasse implementiert werden, aber um von einer abstrakten Klasse abzuleiten, muss man sich da in die Klassenhierachie einfügen - das war in meinem Fall eine bewusste Einschränkung und ausserdem konnte ich bestimmte Methoden bereits in der abstrakten Klasse implementieren. Zudem halte ich mich gerne an einen einfachen Grundsatz, den ich vor langer Zeit mal gelesen hatte: die Superklasse gibt an, was eine Klasse ist und die implementierten Interfaces geben an, was eine Klasse kann.

Ebenfalls nicht einverstanden bin ich mit dem Grundsatz, dass alle Member private sein müssen. Ich habe einen Fall, in dem ich in der abstrakten Oberklasse bestimmte Methoden bereits komplett implementiere - und da drin brauche ich einen logger. Der Logger wird aber erst in den Unterklassen initialisiert (klar: von der abstrakten Klasse kann es ja keine Instanzen geben und dem Logger wird bei der Erzeugung der Name der instanzierten Klasse, in welcher er verwendet wird, mitgegeben). Da ist es viel einfacher, den logger protected zu machen, anstatt dann in den Unterklassen jedesmal mit getLogger darauf zuzugreifen...

Aber eben... ich suche ja bewusst die Diskussion für solche Fragen, um die Ideen hinter den Einschränkungen besser zu verstehen und gegebenenfalls mich oder die Checkstyle-Konfiguration anpassen zu können. Natürlich ist das nicht der Weisheit letzter Schluss, das ist mir klar.
 
Zuletzt bearbeitet:
M

maki

Gast
Der Weg
Interface -> abstrakte Klasse -> kontrekte Klassen bietet mehr flexiblität als abstrakte Klasse -> konkrete klasse und gleichzeitig mehr Entkopplung ;)

Dein Beispiel mit dem logger finde ich nicht gut, sowas gehört nicht in die Vererbungshierarchie, mit aktuellen Loggern (LOG4J, etc.) will man sowieso einen Logger pro loggender Klasse.
 

Lowpass

Aktives Mitglied
hmmm... ich dachte es sei vielleicht nicht so logisch, wenn eine Klasse loggt, die gar nicht instanziert werden kann...

Was die Sache mit Interface -> abstrakte Klasse betrifft: und wenn ich diese Flexibilität bewusst nicht will? Wenn ich nicht will, dass sich da jeder nach Belieben reinhängen kann?
 
M

maki

Gast
Beid er genannten Flexibilität geht es darum, die Nutzer deiner Klassen (interfaces etc.) vor Änderungen zu schützen, kannst dir ja mal die Collections API ansehen.
Und abhängigkeiten zu reinen Interfaces sind immer loser als Abhängigkeiten zu Klassen, selbst abstrakten.
 

Lowpass

Aktives Mitglied
Und abhängigkeiten zu reinen Interfaces sind immer loser als Abhängigkeiten zu Klassen, selbst abstrakten.

Ich rede ja nicht allgemein, sondern von Fällen, in denen man eben keine lose Abhängigkeit wünscht.
Abgesehen davon würde ich gerne mal wissen, wieso Abhängigkeiten zu Interfaces loser sind als zu Klassen:
Das Interface wirst Du kaum ändern können, ohne nicht auch alle implementierenden Klassen zu ändern. Bei abstrakten Klassen kannst Du nicht-abstrakte Methoden beliebig hinzufügen ohne am bestehenden Code irgend etwas ändern zu müssen.

Du meinst wahrscheinlich eher, dass die Abhängigkeiten zur implementierenden Klasse geringer sind.
 
M

maki

Gast
Ich rede ja nicht allgemein, sondern von Fällen, in denen man eben keine lose Abhängigkeit wünscht.
Wann sollte das denn der Fall sein?

Abgesehen davon würde ich gerne mal wissen, wieso Abhängigkeiten zu Interfaces loser sind als zu Klassen:
Das gehört zu den Grundlagen ;)
Nur von einer Schnittstelle abhängig zu sein bezeichnet man als lose Kopplung(vereinfacht ausgedrückt), anstatt von konkreten klassen abhängig zu sein.
Abhängigkeit zu einer Schnittstelle vs. Abhängigkeit zu einer Implementierung!
Denn wenn ich nur vom Interface abhängig bin, brauche ich mir über die Implementierung keine Gedanken zu machen.

Nebenbei, es geht nicht nur darum Änderungen einfacher zu machen, sondern wirklich darum, die Implementierungen auf Wunsch auszutauschen, sehr häufig beim Unit testen zu beobachten (Mocks, Stubs, Fakes...)
Das Interface wirst Du kaum ändern können, ohne nicht auch alle implementierenden Klassen zu ändern. Bei abstrakten Klassen kannst Du nicht-abstrakte Methoden beliebig hinzufügen ohne am bestehenden Code irgend etwas ändern zu müssen.
Das ist doch genau der "Trick" wenn ich Interface <- abstrakte Klasse <- konkrete Klasse habe, ich kann die neuen Methoden in der Abstrakten Klasse implementieren (default).
Das ich das Interface ändern muss wenn ich Methoden hinzufüge ist klar.
 

Lowpass

Aktives Mitglied
Wann sollte das denn der Fall sein?
Wenn man nach aussen hin nicht erweiterbar sein möchte.

Das gehört zu den Grundlagen ;)
Nur von einer Schnittstelle abhängig zu sein bezeichnet man als lose Kopplung(vereinfacht ausgedrückt), anstatt von konkreten klassen abhängig zu sein.
Aber auch die Grundlagen muss man erst einmal verstehen.
Diese lose Kopplung bezieht sich auf die Unabhängigkeit gegenüber den konkreten Implementierungen, nicht aber auf die verwendeten Interfaces.
Änderst Du die Interfaces, musst Du nicht nur den nutzenden Code anpassen, sondern auch sämtliche Implementierungen.
Zudem: alles zu 100% flexibel und austauschbar zu machen entspricht dem YAGNI Anti-Pattern.

Nebenbei, es geht nicht nur darum Änderungen einfacher zu machen, sondern wirklich darum, die Implementierungen auf Wunsch auszutauschen
In meinem Fall gibt es 2 Implementierungen der abstrakten Klasse - und diese können sich nicht gegenseitig ersetzen, sondern existieren nebeneinander - sind 2 Ausprägungen der selben Ober-Klasse. Und es gibt nur diese zwei und darf nur diese zwei geben.
Und falls es eine dritte geben soll, dann will ich sicher sein, dass diese nur und ausschliesslich zu diesem Zweck existiert - und das kann ich ein kleines bisschen erzwingen, indem es eine Subklasse sein muss und nicht einfach ein Interface als eines von womöglich vielen implementieren kann.
Ich will eine 100%ige Unterordnung in die Klassenhierarchie erzwingen.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Checkstyle 100 Zeichen pro Zeile Allgemeine Java-Themen 11
B Checkstyle Allgemeine Java-Themen 6
Mr. Pink Erste Schritte Checkstyle.properties Allgemeine Java-Themen 3
D Checkstyle Plugin Allgemeine Java-Themen 4
M Frage zu Checkstyle Allgemeine Java-Themen 5
N Checkstyle - Design for Extension Allgemeine Java-Themen 4
D FindBugs oder CheckStyle aus Java-Programm starten Allgemeine Java-Themen 2
T CheckStyle, JUnit und FindBugs aus Java-Programm starten Allgemeine Java-Themen 2
M Probleme mit Checkstyle , v.a. Klammersetzung Allgemeine Java-Themen 8
M Exceptions - wann / wie verwenden? Allgemeine Java-Themen 4
LimDul Spezifkation, wann es deprecation Warnings gibt Allgemeine Java-Themen 1
N Streams wann .filtern? Allgemeine Java-Themen 2
perlenfischer1984 Wann ist ein Parameter Check sinnvoll Allgemeine Java-Themen 7
T GUICE- Dependency Injection- WANN nutze ich Providers? Allgemeine Java-Themen 2
B Erkennen, wann Prozess beendet ist, dann Thread beenden. Allgemeine Java-Themen 6
D Wann sollte ich statische Methoden und Variablen benutzen? Allgemeine Java-Themen 44
Rudolf Wann System.exit und wann dispose? Allgemeine Java-Themen 9
X Wann ist Runtime.getRuntime().exec mit Copy fertig? Allgemeine Java-Themen 10
M Wann ist MVC sinnvoll? Allgemeine Java-Themen 14
M Wann Membermethoden, wann statische Utility-Methoden? Allgemeine Java-Themen 24
Ark Wann 64 Bit-Befehle im Einsatz? Allgemeine Java-Themen 6
G Wann normale Exception und wann Runtimeexception Allgemeine Java-Themen 12
Y Wann folgende Technologien benutzen Allgemeine Java-Themen 5
G Parameter oder Attribut (wann nehme ich was?) Allgemeine Java-Themen 12
M Wann verwendet man PropertyChangedEvents, wann eigene? Allgemeine Java-Themen 3
F Wann und wie Exceptions einsetzen? Allgemeine Java-Themen 13
G Wann statische Methoden, statische Attributen? Allgemeine Java-Themen 7
G Ab wann Datenbank verwenden Allgemeine Java-Themen 15
B Wann Interface und wann Adapter Allgemeine Java-Themen 4
B ObjectInputStream - Wann ist Ende erreicht? Allgemeine Java-Themen 10
D Wann ist das ergebnis einer Rechnung eine Double? Allgemeine Java-Themen 7
M Maximal verfügbarer Hauptspeicher? Ab wann wird ausgelagert? Allgemeine Java-Themen 13
P Wann kommt denn nun 1.5 überhaupt? Allgemeine Java-Themen 6
KonradN Mal eine Frage zu Binary Serialization Allgemeine Java-Themen 15
D Hat Java eine Library um JavaScript auszuwerten? Allgemeine Java-Themen 2
dokan wie kann ich eine funktionierende Suchleiste erstellen Allgemeine Java-Themen 1
B Wie erstelle ich dazu eine Abfrage ob der Button gedrückt wurde? Allgemeine Java-Themen 8
J Integration pay Pale in eine JavaFx Desktop Application Allgemeine Java-Themen 1
berserkerdq2 Wenn ich einfach eine GIF in den Scenebuilder als Bild reinpacke, wird das dann asl Gif angezeigt Allgemeine Java-Themen 1
8u3631984 Strukturiertes Logging : Jedes Feld in eine seperate Zeile - aber wie ? Allgemeine Java-Themen 2
berserkerdq2 Gibt es eine saubere Dokumentation von Jfoenix? Allgemeine Java-Themen 1
M Eigene Datenstruktur um eine Menge zu speichern Allgemeine Java-Themen 3
A Wie schreibe ich eine For-Schleife in ein Stream API um? Allgemeine Java-Themen 12
E Es ist nicht möglich, eine Batch-Anweisung auszuführen. Allgemeine Java-Themen 9
T Eine Frage des Designs Allgemeine Java-Themen 2
R Best Practice Erfahrungswerte für eine Migration von JSF nach Angular (oder anderes JS-Framework) Allgemeine Java-Themen 1
H Eine Linie verkürzen Allgemeine Java-Themen 5
N rekursion mehrfach eine Methode Öffnen Allgemeine Java-Themen 4
berserkerdq2 Wenn ich eine Methode nur jede 50ms ausführen will, wie mach ich das? Allgemeine Java-Themen 4
berserkerdq2 Wie synchronisiere ich eine for-Schleife Allgemeine Java-Themen 12
berserkerdq2 Wie mache ich in IJVM eine if verzweigung? Allgemeine Java-Themen 27
F Gibt es mittlerweile eine Alternative zu DaisyDiff Allgemeine Java-Themen 2
_user_q Was brauche ich, um eine eigene "Search for updates"-Funktion einzubauen? Allgemeine Java-Themen 1
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
LimDul Kam eine java.net.URL zu einer HashMap und ging als DNS Anfrage wieder heraus Allgemeine Java-Themen 18
pizza_dox_9999 Wie füge ich eine "eigene" ScriptEngine dem ScriptEngineManager? Allgemeine Java-Themen 3
F Kennt ihr eine Library um 2 HTML Seiten zu diffen? Allgemeine Java-Themen 8
Y ImagePanel von anderer Klasse in eine MainFrame Klasse hinzufügen. Allgemeine Java-Themen 1
OnDemand Anzeigen was eine Applikation macht Allgemeine Java-Themen 1
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
J Eine Frage zu den Threads und Task Allgemeine Java-Themen 1
Tobero Wie bekomme ich in welchem Quadrat sich eine Position in einem Grid befindet Allgemeine Java-Themen 11
Tobero Wie kann man eine Poisson Disc Sampler? Allgemeine Java-Themen 7
M Openjdk - gibt es auch eine Openjre? Allgemeine Java-Themen 7
R Lambda Expression in einer Methode execute() aufrufen (execute() ist eine Methode aus dem funktionalen Interface Command) Allgemeine Java-Themen 5
S Noch eine Design-Frage zu Setter Allgemeine Java-Themen 6
N Arrayliste in eine Datei speichern Allgemeine Java-Themen 4
J Öffnen eine jar-Datei Allgemeine Java-Themen 11
Zrebna Gibt es eine Möglichkeit eine NPE zu vermeiden, wenn null returned wird? Allgemeine Java-Themen 3
S Klassen Einfügen von unbekannter menge an Variablen in eine Klasse mithilfe von ASM Allgemeine Java-Themen 5
R Wo müsste ich im Code eine Änderung vornehmen? Allgemeine Java-Themen 6
S Rückgabe einer HttpURLConnection für eine Seite einlesen bei der man eingeloggt ist..? Allgemeine Java-Themen 5
S Gibt es eine Moeglichkeit die Runtime Ausführung zu analysieren..? Allgemeine Java-Themen 7
S Habt ihr eine Idee wie man Serializierung testen kann..? Allgemeine Java-Themen 6
S Wenn eine Klasse zwei Interfaces mit derselben Methodensignatur implementiert: welche wird aufgerufen? Allgemeine Java-Themen 15
Drachenbauer warum bekomme ich hier eine NullPointerException Allgemeine Java-Themen 6
M Gibt es eine API die den aktuellen Wert eines Indikators beim Trading zurückgibt? Allgemeine Java-Themen 7
X Collections Gibt es eine Klasse welche die Vorteile von List und HashMap vereint, aber konstante Laufzeit (O(1)) hat in Java? Allgemeine Java-Themen 4
N Eine stelle der Fibonacci-Zahlenfolge ausgeben. Allgemeine Java-Themen 4
E Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ? Allgemeine Java-Themen 7
W Collections Suche etwas Sorted-List-Artiges...hat jemand eine Idee? Allgemeine Java-Themen 13
L Methoden Über Reflections eine Methode mit aufrufen Allgemeine Java-Themen 3
S Kann ich eine Methode schreiben die alle Arten von funktionalen Interfaces akzeptiert..? Allgemeine Java-Themen 21
Drachenbauer Wie kann eine vorgegebene Farbe über einen String erkannt werden? Allgemeine Java-Themen 11
J Datenstruktur für eine Map erstellen Allgemeine Java-Themen 2
sascha-sphw Java 9 module Zugriff auf eine resource einer anderen JAR Allgemeine Java-Themen 0
pkm Kann eine ServerSocket-Klasse nicht stateful sein? Allgemeine Java-Themen 4
B Aufruf der Methode ergibt eine Exception Allgemeine Java-Themen 13
I Eine Anwendung so gut wie möglich beschützen Allgemeine Java-Themen 9
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
X Wie mache ich hier eine Rekursion rein ? Allgemeine Java-Themen 7
K OOP Suche Hilfe + Erklärung für eine Hausaufgabe Allgemeine Java-Themen 1
N Über einen Button in JavaFX ein Event über eine Pipeline schicken(Netty) Allgemeine Java-Themen 1
M Login in eine Webseite mit Java Allgemeine Java-Themen 3
A NetBeans Suche Programmierer für eine Belegarbeit Allgemeine Java-Themen 11
D Warum kann ich eine (deflaut) Klasse aus einer Libary in einem anderen Projekt benutzen? Allgemeine Java-Themen 3
L Übergabe an eine eher einfache Java- Applikation wegen Kündigung Allgemeine Java-Themen 1
C Ein Iterator ist eine Implementierung des Interface Iterable? Allgemeine Java-Themen 2
M Schlüsselworte Was ist eine Java Spezifikation + JSR? Allgemeine Java-Themen 11
E RMI NULL-Pointer-Exeception wenn der RMI-Proxy eine Methode deligiert Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben