Ich habe eine Hausaufgabe und muss bewerten, welcher Ansatz gemäß GRASP "Protected Variation" besser ist. Ich habe bei Stack Overflow eine Frage zur Trennung von Header- und Codedateien in C ++ gefunden .
Was ich jedoch wissen möchte, warum Java C ++ nicht folgt, um die Trennung zwischen Klassendefinitionen und Klassenimplementierungen zu fördern. Gibt es Vorteile bei der Java-Methode gegenüber der C ++ - Methode?
java
programming-languages
c++
Etienne Noël
quelle
quelle
private
, damit die Implementierung die Größe kennt und dieprivate
Elementfunktionen auch funktionieren.Antworten:
Wie viele Codezeilen enthält das folgende Programm?
Sie haben wahrscheinlich mit 7 geantwortet (oder mit 6, wenn Sie die leere Zeile nicht gezählt haben, oder mit 4, wenn Sie die geschweiften Klammern nicht gezählt haben).
Ihr Compiler sieht jedoch etwas ganz anderes:
Ja, das sind 18,7 KLOC nur für eine "Hallo Welt!" Programm. Der C ++ - Compiler muss das alles analysieren . Dies ist ein Hauptgrund, warum die C ++ - Kompilierung im Vergleich zu anderen Sprachen so lange dauert und warum moderne Sprachen Header-Dateien meiden.
Eine bessere Frage wäre
Warum hat C ++ Header-Dateien?
C ++ wurde als Obermenge von C entwickelt, daher mussten Header-Dateien aus Gründen der Abwärtskompatibilität aufbewahrt werden.
OK, warum hat C Header-Dateien?
Wegen seines primitiven separaten Kompilierungsmodells. Die von C-Compilern generierten Objektdateien enthalten keine Typinformationen. Um Typfehler zu vermeiden, müssen Sie diese Informationen in Ihren Quellcode aufnehmen.
Das Hinzufügen der richtigen Typdeklarationen behebt den Fehler:
Beachten Sie, dass es keine
#include
s gibt. Wenn Sie jedoch eine große Anzahl externer Funktionen verwenden (was die meisten Programme tun), wird das manuelle Deklarieren dieser Funktionen mühsam und fehleranfällig. Es ist viel einfacher, Header-Dateien zu verwenden.Wie können moderne Sprachen Header-Dateien vermeiden?
Durch Verwendung eines anderen Objektdateiformats, das Typinformationen enthält. Das Java * .class-Dateiformat enthält beispielsweise "Deskriptoren", die die Feldtypen und Methodenparameter angeben.
Dies war keine neue Erfindung. Früher (1987), als Borland Turbo Pascal 4.0 separat kompilierte "Einheiten" hinzufügte, entschied es sich, ein neues
*.TPU
Format anstelle von Turbo C zu*.OBJ
verwenden, um die Notwendigkeit von Header-Dateien zu beseitigen.quelle
OBJ
Dateien ausgibt , anstattTPU
s ...Java verfügt über Schnittstellen zum Definieren eines Vertrags. Dies bietet eine höhere Abstraktionsebene von den Anforderungen des Aufrufers und der tatsächlichen Implementierung. Das heißt, der Aufrufer muss die implementierende Klasse nicht kennen, er muss nur den Vertrag kennen, den er unterstützt.
Angenommen, Sie möchten eine Methode schreiben, die alle Schlüssel / Werte in einer Map verlangsamt.
Diese Methode kann entrySet () auf einer abstrakten Schnittstelle aufrufen, die aus der Klasse entfernt wird, die sie implementiert. Sie können diese Methode mit aufrufen.
quelle
#define interface class
.virtual
Schlüsselwort nicht mehr verwenden müssen, um Polymorphismus zu erhalten, und dies hat keine Leistungseinbußen zur Folge, wenn Sie nur einen oder zwei konkrete Typen verwenden, wie sie in Java sind. Können Sie mich auf eine Dokumentation verweisen, wie dies in C ++ funktioniert?Überschriften existieren, ganz offen gesagt, als historischer Unfall. Es ist ein unglaublich schlechtes System, keine andere Sprache hat etwas so Schreckliches, und jeder, der sich nicht mit ihnen befassen muss, sollte sich freuen.
quelle
Überschriften ermöglichen eine separate Kompilierung. Durch das Einschließen der Header muss der Compiler nichts über die Binärstruktur des kompilierten C ++ - Codes wissen und kann diesen Job einem separaten Linker überlassen. Java verwendet mit seinem Compiler keinen separaten Linker. Da .class-Dateien streng definiert sind, kann der Compiler sie lesen, um alle Mitglieder mit all ihren Typen zu bestimmen, ohne sie in jeder Kompilierungseinheit erneut deklarieren zu müssen.
Sie können die gesamte Implementierung in einen C ++ - Header aufnehmen, der Compiler kompiliert sie jedoch jedes Mal neu, wenn sie # eingeschlossen ist, und zwingt den Linker, die doppelten Kopien zu sortieren und zu verwerfen.
quelle
Java fördert die Trennung von Klassendefinition und -implementierung. Es hängt nur davon ab, von wo aus Sie suchen.
Wenn Sie der Autor einer Java-Klasse sind, sehen Sie die Definition der Klasse sowie deren Implementierung in einer Datei. Dies vereinfacht den Entwicklungsprozess, da Sie nur an einen Ort gehen müssen, um die Klasse zu verwalten. Sie müssen nicht zwischen zwei Dateien wechseln (.h und .cpp wie in C ++). Wenn Sie jedoch der Konsument der Klasse sind, behandeln Sie die Definition nur über eine .class-Datei, die entweder in einer .jar- oder einer eigenständigen .class-Datei gepackt ist
Mit C ++ können Sie die Definition und Implementierung trennen, dies ist jedoch ad-hoc. Zum Beispiel hindert Sie nichts daran, die Methode inline in die Header-Datei zu schreiben, und für Vorlagenklassen ist dies obligatorisch. In der Header-Datei werden auch alle Mitgliedsvariablen aufgelistet, die für jeden sichtbar sind, der sich die Header-Datei ansieht, obwohl sie ein Implementierungsdetail der Klasse sind und für einen Verbraucher irrelevant sind.
quelle