Ich bin sehr neu in der Programmierung und ein bisschen verwirrt, weil ich verschiedene Konventionen aus verschiedenen Quellen gelesen und gehört habe:
Hat die objektorientierte Programmierung 4 oder 5 Konzepte?
Als Neuling verstehe ich, dass dies die 5 Konzepte sind:
- Abstraktion
- Erbe
- Verkapselung
- Polymorphismus
- Modularität
Wie kommt es also, dass ich keine "strengere" Definition finde und es da draußen mehrere Anordnungen dieser Konzepte zu geben scheint?
object-oriented
JohnDoea
quelle
quelle
Antworten:
Der Grund, warum Sie unterschiedliche Erklärungen dafür finden, was objektorientierte Programmierung bedeutet, ist, dass es keine einzelne Person oder Organisation gibt, die befugt ist, eine strikte universell anwendbare Definition zu formulieren.
Objektorientierte Programmierung ist kein ISO-Standard oder wissenschaftliches Gesetz. Es ist eine Philosophie. Und wie bei allen Philosophien gibt es alle möglichen unterschiedlichen Interpretationen und keine Interpretation ist universell anwendbar. Wenn Sie einen Text lesen, der Ihnen sagt, welchen Konzepten Sie beim Entwerfen einer Softwarearchitektur folgen sollten, sollten Sie dies als Richtlinie betrachten, die auf den Meinungen basiert, die der Autor während seiner Berufserfahrung gebildet hat, und nicht als universelle Wahrheit.
quelle
Wie andere bereits erwähnt haben, enthält "OO" eigentlich keine Komponenten , da es sich um eine Denkweise zur Modellierung von Problemlösungen handelt und nicht um ein Toolkit oder eine Reihe klar definierter Prozesse.
Vererbung und Polymorphismus sind Programmiersprachenmerkmale. Es ist gut, dass Sie diese verstehen, aber denken Sie daran , dass es sich um Werkzeuge handelt (was bedeutet, dass sie wie alle anderen Werkzeuge nur zur Lösung spezifischer Probleme verwendet werden sollten und nicht als Ziel oder Ziel behandelt werden sollten). Sie können (und sollten oft) "OO" -Code schreiben, ohne einen von beiden zu verwenden. Einige der besten "OO" -Codes, die ich je gesehen habe, verwenden Vererbung oder Polymorphismus nur sehr wenig.
Abstraktion, Kapselung und Modularität haben weniger mit Code zu tun als vielmehr mit der Art und Weise, wie Sie ein Problem betrachten, wie Sie versuchen, dieses Problem zu verstehen und wie Sie Ihre Lösung im Code entwerfen und strukturieren.
Diese Designideen sind auch nicht exklusiv für "OO". Es besteht die Möglichkeit, dass Sie sie jetzt auf einer grundlegenden Ebene verstehen, einschließlich der Möglichkeit, eine lehrbuchgenaue Definition zu erklären und sie auf etwas nicht triviale Probleme anzuwenden. Obwohl ein tieferer Test des Verständnisses ein sehr großes komplexes Problem darstellt und wie viel Komplexität Sie bewältigen können.
Ein weiterer Test für das Verständnis ist der Ansatz, mit dem Sie ein Problem auflösen. und Neulinge bei "OO", die häufig in Bezug auf Datenmodellierung über OO unterrichtet werden (weil die meisten Menschen dies in den 1990er Jahren so verstanden haben) und sich häufig auf die falschen Aspekte eines Problems konzentrieren - dh sie konzentrieren sich zu viel auf Daten, und sie konzentrieren sich nicht genug auf das Verhalten.
Siehe beispielsweise klassische Beispiele oft Entitäten wie
Dog
,Cat
,Elephant
,Seagull
,Shark
sucht oft usw. Neuankömmlinge „OO“ an solchen Beispielen und sofort denken : „Oh, ich brauche eine Basisentität genanntAnimal
“ , und sie können sogar mit anderem Ende Zwischenentitäten wieMammal
undAmphibian
in einer ordentlichen Erbschaft mit unterschiedlichen Attributen.Während diese Denkweise ein sehr grundlegendes Verständnis mehrerer OO-Konzepte demonstriert , würde ein erfahrener OO-Programmierer niemals so vorgehen oder zu dieser Schlussfolgerung springen (und sich tatsächlich beschweren, dass sie nicht genügend Informationen haben), weil dieser Ansatz Entität demonstriert Modellierung statt OO-Modellierung, und weil das erfundene Beispiel nichts über das Verhalten dieser Tiere aussagt (und viele Menschen würden heutzutage argumentieren, dass die Essenz von OO alles im Verhalten und in der Funktionalität liegt).
Der Weg zum Erlernen von "OO" besteht traditionell darin, Zeit damit zu verbringen, die falschen Abstraktionen aufzubauen, wenn Sie entweder nichts (oder zu wenig) über das Verhalten des Problems wissen, das Sie modellieren, oder wenn Sie den Fehler machen, Ihre Aufmerksamkeit eher auf Entitäten als auf Entitäten zu richten Funktionalität, obwohl ein Teil davon darin besteht, dass so viele Bücher, Kurse und Online-Tutorials, die im Laufe der Jahre geschrieben wurden, die Lernenden lange Zeit (falsch) auf diesem Weg geführt haben (die Gezeiten ändern sich jedoch).
Insgesamt wird ein Großteil Ihres Verständnisses auf Erfahrung zurückzuführen sein. Diese Konzepte, die Sie bisher gelernt haben, sind ein guter Anfang. Es gibt weitere Konzepte, die Sie auf Ihrem Weg lernen müssen (z. B. "SOLID" - und "DRY" -Prinzipien), und Sie müssen viel Zeit mit dem Putten verbringen Theorie in die Praxis mit wirklich hochkomplexen Problemen, bevor alles wahrscheinlich "einrastet".
quelle
Der Begriff "Objektorientierung" wurde von Dr. Alan Kay geprägt, daher ist er die maßgebliche Quelle für das, was er bedeutet, und er definiert ihn folgendermaßen :
Lassen Sie uns das aufschlüsseln:
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. Spätes Binden 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 einmal 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 über eine Methode verfügt), ob sie die Nachricht an eine andere Person weitergeleitet haben (Delegierung / Proxy), ob sie sie überhaupt verstanden haben. Darum geht es bei der Kapselung, 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 "modernerer" Begriff für "Messaging" ist "dynamischer Methodenversand" oder "virtueller Methodenaufruf", aber das verliert die Metapher und konzentriert sich auf den Mechanismus.
Es gibt also zwei Möglichkeiten, die Definition von Alan Kay zu betrachten: Wenn Sie sie für sich allein betrachten, können Sie feststellen, dass Messaging im Grunde genommen ein spät gebundener Prozeduraufruf ist und eine späte Bindung eine Kapselung impliziert, sodass wir daraus schließen können, dass # 1 und # 2 sind tatsächlich redundant, und bei OO dreht sich alles um spätes Binden.
Später stellte er jedoch klar, dass das Wichtigste das Versenden von Nachrichten ist, sodass wir es aus einem anderen Blickwinkel betrachten können: Das Versenden von Nachrichten ist spät. Nun, wenn Messaging das ist nur etwas möglich, dann würde # 3 triviale Weise wahr sein: wenn es nur eine Sache, und das Ding ist spät gebunden, dann alle die Dinge spät gebunden. Und wieder folgt die Kapselung aus dem Messaging.
Ähnliche Punkte werden auch in On Understanding Data Abstraction, überarbeitet von William R. Cook, und in seinem Vorschlag für vereinfachte, moderne Definitionen von "Objekt" und "Objektorientiert" gemacht .
In Smalltalk-72 gab es nicht einmal Objekte! Es gab nur Nachrichtenströme, die analysiert, umgeschrieben und umgeleitet wurden. Zuerst kamen Methoden (Standardmethoden zum Parsen und Umleiten der Nachrichtenströme), später 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. Hätte Kays Forschungsgruppe bereits über Prototypen gewusst, hätten sie wahrscheinlich nie Klassen eingeführt.
Benjamin Pierce in Typen und Programmiersprachen argumentiert, dass das definierende Merkmal der Objektorientierung die offene Rekursion ist .
Also: Laut Alan Kay dreht sich bei OO alles um Messaging. Laut William Cook dreht sich bei OO alles um den dynamischen Versand von Methoden (was wirklich dasselbe ist). Laut Benjamin Pierce dreht sich bei OO alles um Open Recursion, was im Grunde bedeutet, dass Selbstreferenzen dynamisch aufgelöst werden (oder zumindest darüber nachdenken) oder mit anderen Worten, Messaging.
Wie Sie sehen können, hat die Person, die den Begriff "OO" geprägt hat, eine eher metaphysische Sicht auf Objekte, Cook eine eher pragmatische Sicht und Pierce eine sehr strenge mathematische Sicht. Aber das Wichtigste ist: Der Philosoph, der Pragmatiker und der Theoretiker sind sich einig! Messaging ist die einzige Säule von OO. Zeitraum.
Beachten Sie, dass hier keine Vererbung erwähnt wird! Vererbung ist für OO nicht wesentlich. Im Allgemeinen haben die meisten OO-Sprachen eine Möglichkeit zur Wiederverwendung der Implementierung, dies muss jedoch nicht unbedingt eine Vererbung sein. Es könnte zum Beispiel auch eine Form der Delegation sein. Tatsächlich wird im Vertrag von Orlando die Delegation als Alternative zur Vererbung erörtert und wie unterschiedliche Formen der Delegation und Vererbung zu unterschiedlichen Entwurfspunkten innerhalb des Entwurfsraums objektorientierter Sprachen führen. (Beachten Sie, dass selbst in Sprachen, die die Vererbung unterstützen, wie Java, tatsächlich gelernt wird, dies zu vermeiden, was wiederum darauf hinweist, dass dies für OO nicht erforderlich ist.)
quelle
Wie @Philipp feststellt, liegt die Wurzel des Problems darin, dass es keine offizielle Definition dafür gibt, was eine Programmiersprache objektorientiert macht. In der Tat ist dies wahrscheinlich eine gute Sache. Es gibt viele Möglichkeiten, die OO-Programmierung zu unterstützen, jede mit ihren eigenen Vor- und Nachteilen. Die Diskussion darüber, welche Sprachen "reiner OO" sind, bringt nicht wirklich viel.
Wenn ich mir jedoch die 5 Attribute ansehe, die Sie aufgelistet haben, ist Modularität meiner Meinung nach definitiv die ungerade. Modularität ist wirklich ein Attribut eines Programms, keine Programmiersprache. Auf sprachlicher Ebene lautet das Attribut "Unterstützung für die Modularisierung", und dies erfolgt normalerweise in Form eines "Moduls" -Pr "-Pakets" -Mechanismus.
Mein eigentlicher Einwand gegen die Modularität ist jedoch, dass sie für die OO-Programmierung oder die OO-Programmiersprachen nicht von entscheidender Bedeutung ist, da die archetypische Programmiersprache Smalltalk-80 überhaupt keine Module unterstützt. Und wenn Sie darüber nachdenken, ist die sprachliche Unterstützung für Module in vielen weit verbreiteten OOPLs "schwach".
Module unterstützen "Programmieren im großen Stil" ... wobei Ihre Codebasis zu groß wird, als dass eine einzelne Person sie vollständig verstehen könnte. Und Sie nicht brauchen Module in einer Programmiersprache Code modularisieren.
Ich komme noch nicht in die Debatte über die anderen 4 Attribute und ob (zum Beispiel) welche Modelle der "Vererbung" reine OO sind. Auch wenn Alan Kay die Erfindung der OO-Programmierung zugeschrieben wird, bedeutet dies nicht unbedingt, dass seine Definitionen von OO / und OOPL Vorrang haben. Dies ist eindeutig nicht der Fall. Er ist eine maßgebliche Quelle, aber es gibt andere Quellen, die andere Definitionen für OO & OOPLs geben, die (in der Praxis) ein größeres Gewicht haben.
quelle