Ich denke, C ist vollkommen in Ordnung und anständig, um objektorientierte Konzepte zu implementieren, achselzucken . Die meisten meiner Ansicht nach bestehenden Unterschiede zwischen der Untergruppe der objektorientierten Sprachen mit gemeinsamem Nenner sind aus meiner pragmatischen Sicht geringfügig und syntaktisch.
Beginnen wir zum Beispiel mit dem Verstecken von Informationen. In C können wir dies erreichen, indem wir einfach die Definition einer Struktur verbergen und mit undurchsichtigen Zeigern arbeiten. Das modelliert effektiv die public
vs. private
Unterscheidung von Datenfeldern, wie wir sie mit Klassen erhalten. Und es ist einfach genug und kaum anti-idiomatisch, da die Standard-C-Bibliothek in hohem Maße darauf angewiesen ist, Informationen zu verbergen.
Natürlich verlieren Sie die Möglichkeit, die genaue Speicherzuordnung der Struktur mithilfe von undurchsichtigen Typen einfach zu steuern, aber das ist nur ein bemerkenswerter Unterschied zwischen beispielsweise C und C ++. C ++ ist definitiv ein überlegenes Werkzeug, wenn es darum geht, objektorientierte Konzepte über C zu programmieren und dabei die Kontrolle über Speicherlayouts zu behalten. Dies bedeutet jedoch nicht unbedingt, dass Java oder C # C in dieser Hinsicht überlegen sind, da diese beiden Funktionen Sie überzeugen verlieren vollständig die Fähigkeit zu steuern, wo Objekte im Speicher zugeordnet sind.
Und wir müssen eine Syntax verwenden, fopen(file, ...); fclose(file);
die sich von der von file.open(...); file.close();
Big Whoop unterscheidet. Wen interessiert das schon? Vielleicht nur jemand, der sich in seiner IDE stark auf die automatische Vervollständigung stützt. Ich gebe zu, dass dies aus praktischer Sicht eine sehr nützliche Funktion sein kann, aber möglicherweise keine, die eine Diskussion darüber erfordert, ob eine Sprache für OOP geeignet ist.
Uns fehlt die Fähigkeit, protected
Felder effektiv umzusetzen . Ich werde dort total einreichen. Ich glaube jedoch nicht, dass es eine konkrete Regel gibt, die besagt: " Alle OO-Sprachen sollten über eine Funktion verfügen, die es Unterklassen ermöglicht, auf Mitglieder einer Basisklasse zuzugreifen, auf die normale Clients immer noch nicht zugreifen sollten ." Außerdem sehe ich selten Anwendungsfälle für geschützte Mitglieder, die zumindest nicht ein bisschen misstrauisch sind, eine Wartungshürde zu werden.
Und natürlich müssen wir den OO-Polymorphismus mit Tabellen von Funktionszeigern und Zeigern auf sie "emulieren", um einen dynamischen Versand mit etwas mehr Boilerplate zu ermöglichen, um diese analogen vtables
und vptrs
, aber ein bisschen Boilerplate hat mir nie viel Leid bereitet.
Vererbung ist ähnlich. Wir können das leicht durch Komposition modellieren, und bei der internen Arbeitsweise von Compilern läuft es auf dasselbe hinaus. Natürlich verlieren wir die Typensicherheit , wenn wir einen Downcast ausführen möchten , und da würde ich sagen, wenn Sie überhaupt einen Downcast ausführen möchten , verwenden Sie bitte kein C dafür, da die Dinge, die die Leute in C tun, um einen Downcast zu emulieren, fürchterlich sein können Sicherheitsstandpunkt, aber ich möchte, dass die Leute überhaupt nicht niedergeschlagen sind . Typensicherheit ist etwas, das Sie in C leicht übersehen können, da der Compiler so viel Spielraum bietet, um Dinge wie Bits und Bytes zu interpretieren, was die Fähigkeit einbüßt, mögliche Fehler zur Kompilierungszeit abzufangen, aber einige Sprachen als objektorientiert betrachtet werden nicht einmal statisch getippt.
Also keine Ahnung, ich denke es ist in Ordnung. Natürlich würde ich C nicht verwenden, um eine große Codebasis zu erstellen, die den SOLID-Prinzipien entspricht, aber dies liegt nicht unbedingt an den Mängeln in der objektorientierten Front. Viele der Funktionen, die ich vermissen würde, wenn ich versuchen würde, C für einen solchen Zweck zu verwenden, würden mit Sprachfunktionen zusammenhängen, die nicht direkt als Voraussetzung für OOP angesehen werden, wie z. B. starke Typensicherheit, Destruktoren, die automatisch aufgerufen werden, wenn Objekte den Gültigkeitsbereich verlassen, Operator Überladung, Vorlagen / Generika und Ausnahmebehandlung. Es ist, wenn ich die Zusatzfunktionen vermisse, die ich für C ++ erreiche.