Eines Tages ging ich zu einem Stapelüberlauf-Chat und sah eine Phrase, die besagte, dass Vererbung, Einkapselung und Polymorphismus die Säulen von OOP sind (in dem Sinne, dass sie grundlegend sind, eine Konstruktionssohle).
Es gibt auch eine ähnliche Frage, die mir bei College-Prüfungen und Vorstellungsgesprächen sehr oft gestellt wurde, und die richtige Antwort war immer die im Titel der Frage ausgesprochene Aussage ("Ja, Vererbung, Verkapselung und Polymorphismus sind die Säulen von OOP ).
Aber im Stapelüberlauf-Chat wurde ich ernsthaft verspottet, die Teilnehmer waren mit einer solchen Aussage überhaupt nicht einverstanden. Also, was ist los mit dieser Aussage?
Scheint Programmierer in postsowjetischen und US-amerikanischen Colleges in verschiedenen Dingen ausgebildet zu sein?
Werden Vererbung, Verkapselung und Polymorphismus von US / UK-Programmierern nicht als die Säulen von OOP angesehen?
quelle
Antworten:
Sie werden von vielen Programmierern als Säulen betrachtet, und viele Colleges lehren OO auf diese Weise.
Leider ist es auch eine kurzsichtige Ansicht.
OOP hat sehr wenig Fundament, da es in Wirklichkeit sehr konzeptionell ist: "Gehen Sie auf die Gestaltung Ihres Programms zu, indem Sie die Dinge als Objekte betrachten - zusammenhängende Daten- und Funktionsbündel."
Und während modernes Programmdesign eine schlechte Sicht auf "reine OO- Arbeitsweise " hat, sind sich die meisten erfahrenen Programmierer einig, dass die SOLID-Prinzipien (oder eine Teilmenge davon) bessere Kandidaten für die "Säulen objektorientierter Programmierung" sind (obwohl sie es sind) gut auf Nicht-OOP anwenden). Diese funktionieren überhaupt nicht mit diesen Begriffen. Stattdessen verwenden sie die Konzepte von Softwareentitäten (von denen Objekte eine sind), Schnittstellen (von denen C # / Java / usw.
interface
eine ist), Abstraktion und Untertypisierung (von denen Vererbung eine Form ist).quelle
tl; dr: Sie können Vererbung ohne OO haben, Sie können Verkapselung ohne OO haben, Sie können Polymorphismus ohne OO haben, Sie können sogar alle drei auf einmal ohne OO haben. Auf der Rückseite können Sie OO ohne Vererbung haben. Außerdem gibt es verschiedene Arten der Einkapselung (ADT-orientiert und OO). IOW ist nicht jede Einkapselung OO.
Lange Version:
Der Begriff "Objektorientierte Programmierung" wurde von Alan Kay erfunden, damit er entscheiden kann, was es bedeutet. Und er definiert es so :
In Bezug auf die Implementierung ist Messaging ein spät gebundener Prozeduraufruf. Wenn Prozeduraufrufe spät gebunden sind, können Sie zur Entwurfszeit nicht wissen, was Sie aufrufen werden, sodass Sie keine Annahmen über die konkrete Darstellung des Status treffen können. Es geht also wirklich um Messaging. Late-Binding ist eine Implementierung von Messaging, und die Kapselung ist eine Folge davon.
Später stellte er klar, dass " die große Idee" Messaging "ist, und bedauert, sie" objektorientiert "statt" nachrichtenorientiert "genannt zu haben, weil der Begriff" objektorientiert "den Fokus auf das Unwichtige (Objekte) legt ) und lenkt von dem ab, was wirklich wichtig ist (Messaging):
(Natürlich konzentrieren sich die meisten Menschen heute nicht mehr auf Objekte, sondern auf Klassen, was noch falscher ist.)
Messaging ist für OO sowohl als Metapher als auch als Mechanismus von grundlegender Bedeutung .
Wenn Sie jemandem eine Nachricht senden, wissen Sie nicht, was er damit macht. Das einzige, was Sie beobachten können, ist ihre Reaktion. Sie wissen nicht, ob sie die Nachricht selbst verarbeitet haben (dh ob das Objekt eine Methode hat), ob sie die Nachricht an eine andere Person weitergeleitet haben (Delegation / Proxying) oder ob sie sie überhaupt verstanden haben. Darum geht es bei der Verkapselung, darum geht es bei OO. Sie können einen Proxy nicht einmal von der Realität unterscheiden, solange er so reagiert, wie Sie es erwarten.
Ein "moderner" Begriff für "Messaging" ist "dynamischer Methodenversand" oder "virtueller Methodenaufruf", der jedoch die Metapher verliert und sich auf den Mechanismus konzentriert.
Ähnliche Punkte finden sich auch in On Understanding Data Abstraction, überarbeitet von William R. Cook, und in seinem Vorschlag für vereinfachte, moderne Definitionen von "Objekt" und "objektorientiert" .
In Smalltalk-72 gab es nicht einmal Gegenstände! Es gab nur Nachrichtenströme, die analysiert, umgeschrieben und umgeleitet wurden. Zuerst kamen Methoden (Standardmethoden zum Parsen und Umleiten der Nachrichtenströme), später kamen Objekte (Gruppierungen von Methoden, die einen privaten Status gemeinsam haben). Die Vererbung erfolgte viel später, und Klassen wurden nur eingeführt, um die Vererbung zu unterstützen. Wäre Kays Forschungsgruppe bereits über Prototypen informiert gewesen, hätte sie wahrscheinlich niemals Klassen eingeführt.
Jeder Programmierer sollte " Über das Verständnis der Datenabstraktion" lesen . Es wird detailliert erläutert, worin genau der Unterschied zwischen Objekten und abstrakten Datentypen besteht. Er gibt Beispiele mit Java, und das ist für diese Frage äußerst relevant, da er sowohl in den ADT-Beispielen als auch in den Object-Beispielen Vererbung, Kapselung und Polymorphismus verwendet, aber nur eines der Beispiele objektorientiert ist! Mit anderen Worten: Sie können Vererbung, Einkapselung und Polymorphismus haben, Sie können sogar alle drei auf einmal haben und haben immer noch keine OO.
Auf der anderen Seite können Sie OO ohne Vererbung haben. Wie ich oben angedeutet habe: Die Originalversionen von Smalltalk (die von Alan Kay, dem Erfinder des Begriffs "objektorientierte Programmierung", entworfene Sprache) hatten keine Vererbung.
Last but not least diskutiert der Vertrag von Orlando die Delegation als Alternative zur Vererbung und wie unterschiedliche Formen der Delegation und Vererbung zu unterschiedlichen Gestaltungspunkten im Gestaltungsraum objektorientierter Sprachen führen. (Beachten Sie, dass die Leute auch in Sprachen, die Vererbung unterstützen, wie Java, tatsächlich lernen, dies zu vermeiden, was wiederum darauf hinweist, dass dies für OO nicht erforderlich ist.)
quelle