Warum gibt es für OOP keine einheitliche Definition wesentlicher Konzepte?

12

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?

JohnDoea
quelle
7
Vielleicht, weil das nicht wie Mathematik ist (einige Konzepte in CS sind es, aber ich denke, OOP gehört nicht in diese Kategorie), also gibt es zunächst keine strengen Definitionen. Wie wichtig ist beispielsweise die Modularität? Ist es für OOP wirklich so besonders, dass wir es erwähnen müssen, oder wäre es nur etwas, das von selbst passiert, wenn wir die anderen vier richtig anwenden? Einige Listen fügen 'Hierarchie' hinzu, aber ist dies wirklich etwas Besonderes oder folgt es nur aus Vererbung und Polymorphismus?
Thorsten Müller
6
Tipp: Als sehr neuer Programmierer sollten Sie nicht so sehr darauf aus sein, Terminologie und Theorie zu verstehen. Sammeln Sie zuerst einige praktische Programmiererfahrungen, und es wird viel offensichtlicher, worüber diese Leute sprechen.
Philipp
9
Eine andere Sache ist, dass sich OOP im Laufe der Zeit ändert. In den frühen C ++ - Tagen (ich weiß, dass OOP noch weiter zurückreicht) lag der Schwerpunkt auf Vererbung und Polymorphismus. Der heutige Fokus liegt viel mehr auf Abstraktion und Verkapselung.
Bent
3
Einige interessante Diskussionen über die mangelnde Genauigkeit bei der Definition von OO finden Sie hier: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
MichelHenrich

Antworten:

27

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.

Philipp
quelle
12

Hat die objektorientierte Programmierung 5 oder 4 Komponenten?

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.

Als Neuling verstehe ich, dass dies die 5 Komponenten sind:

Abstraktion, Vererbung, Verkapselung, Polymorphismus und Modularität?

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, Sharksucht oft usw. Neuankömmlinge „OO“ an solchen Beispielen und sofort denken : „Oh, ich brauche eine Basisentität genannt Animal , und sie können sogar mit anderem Ende Zwischenentitäten wie Mammalund Amphibianin 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".

Ben Cottrell
quelle
2
Ein Hai und ein Frosch schwimmen beide, aber einer ist ein Fisch, der andere ist eine Amphibie. Ich denke, dieses Beispiel beschreibt Ihren Standpunkt gut.
RubberDuck
10

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 :

OOP bedeutet für mich nur Messaging, lokale Aufbewahrung und Schutz sowie das Verstecken von Staatsprozessen und die extreme Spätbindung aller Dinge.

Lassen Sie uns das aufschlüsseln:

  • Messaging ("Versand virtueller Methoden", wenn Sie mit Smalltalk nicht vertraut sind)
  • Zustandsprozess sollte sein
    • lokal beibehalten
    • geschützt
    • versteckt
  • extreme Spätbindung aller Dinge

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):

Nur eine sanfte Erinnerung daran, dass ich mir bei der letzten OOPSLA einige Mühe gegeben habe, um alle daran zu erinnern, dass Smalltalk nicht nur NICHT seine Syntax oder die Klassenbibliothek ist, es geht nicht einmal um Klassen. Es tut mir leid, dass ich vor langer Zeit den Begriff "Objekte" für dieses Thema geprägt habe, weil es viele Leute dazu bringt, sich auf die geringere Idee zu konzentrieren.

Die große Idee ist "Messaging" - darum geht es beim Kernal von Smalltalk / Squeak (und es ist etwas, das in unserer Xerox PARC-Phase nie ganz abgeschlossen wurde). Die Japaner haben ein kleines Wort - ma - für "das, was dazwischen liegt" - vielleicht ist das nächste englische Äquivalent "interstitial". Der Schlüssel zur Entwicklung großartiger und erweiterbarer Systeme liegt viel mehr darin, die Kommunikation der Module zu bestimmen, als in ihren internen Eigenschaften und Verhaltensweisen. Denken Sie an das Internet - um zu leben, muss es (a) viele verschiedene Arten von Ideen und Realisierungen zulassen, die über einen einzelnen Standard hinausgehen, und (b) unterschiedliche Grade sicherer Interoperabilität zwischen diesen Ideen ermöglichen.

(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 .

Der dynamische Versand von Operationen ist das wesentliche Merkmal von Objekten. Dies bedeutet, dass die aufzurufende Operation eine dynamische Eigenschaft des Objekts selbst ist. Operationen können nicht statisch identifiziert werden, und es gibt im Allgemeinen keine Möglichkeit, genau zu bestimmen, welche Operation als Antwort auf eine bestimmte Anforderung ausgeführt wird, außer durch Ausführen. Dies ist genau das gleiche wie bei erstklassigen Funktionen, die immer dynamisch versendet werden.

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.)

Jörg W Mittag
quelle
1
@DavidArno Dein Kommentar ist überhaupt nicht konstruktiv. Alan Kay selbst behauptet, er habe den Begriff "Objekt" für dieses Konzept geprägt (allerdings nicht das Konzept selbst). Wenn Sie einer bekannten Autorität in diesem Bereich widersprechen wollen, schreiben Sie zumindest einen konstruktiveren Kommentar.
Andres F.
1
@ DavidArno Auch ist die Abwertung Ihre? Jemand hat sich also die Zeit genommen, eine umfassende Liste verschiedener Ansichten von bekannten Experten darüber zu schreiben, was OOP bedeutet, und Sie haben es abgelehnt, weil Sie mit einem einzigen Satz nicht einverstanden sind? Oookay.
Andres F.
2
@AndresF. Diese Antwort kann wie folgt zusammengefasst werden: "Es gibt zwei Schulen, Alan Kay und alle anderen. Weil der erstere den Begriff geprägt hat, hat er automatisch Recht und jeder, der mit ihm nicht einverstanden ist, ist falsch." Es ist ein Appell an die Autoritätsfehlerantwort. Also das Downvote.
David Arno
2
Tatsächlich kann diese Antwort wie folgt zusammengefasst werden: "Es gibt drei Denkschulen, die aus drei völlig unterschiedlichen Blickwinkeln kommen, und niemand ist mit jemandem anderer Meinung, tatsächlich sind sich alle einig." Der linguistische Verschreiber würde sagen, Alan Kay hat den Begriff erfunden, er kann sagen, was er bedeutet, und er sagt, er bedeutet Messaging. Der linguistische Deskriptivist würde sagen, nein, Alan Kay kann nichts sagen, wir müssen uns ansehen, wie der Begriff tatsächlich verwendet wird , und genau das hat Cook getan: Er hat untersucht, welche Sprachen allgemein als OO (Java, C ++) bezeichnet werden , C # usw.) gemeinsam haben, und er fand
Jörg W Mittag
3
Eine Sache: Messaging. Er untersuchte, welche Sprachen, die üblicherweise als nicht OO bezeichnet werden, nicht den Sprachen entsprechen, die allgemein als OO bezeichnet werden, und er fand eine Sache: Messaging. Der Theoretiker des Elfenbeinturms nimmt den λ-Kalkül und untersucht, was die kleinste Menge von Merkmalen ist, die man hinzufügen müsste, um etwas zu erhalten, das allgemein als OO bezeichnet wird, und kommt zu einer offenen Rekursion , die im Grunde der Baustein für Messaging ist .
Jörg W Mittag
3

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.

Stephen C.
quelle
2
+1 Modularität wird in der Tat allgemein als wünschenswertes Attribut der meisten Softwaresysteme akzeptiert, unabhängig von der verwendeten Programmiersprache und dem verwendeten Paradigma. Viele Sprachen, die nicht OO sind, unterstützen die Modularisierung.
Andres F.
+1 @AndresF. Kommentar. In der Tat kommen "strukturierte Programmierung" und "schrittweise Verfeinerung" (eine Technik zum Denken der Codestruktur) aus dem Schmelztiegel der "zunehmenden Komplexität, die zu noch schlechterer Software führt". Wäre es COBOL vorausgegangen, hätte die Sprache meiner Meinung nach keinen so negativen Ruf. Und ich betrachte OO pragmatisch einfach als Struktur höherer Ordnung. Und ich meine, dass ohne zugrunde liegende Struktur OO nicht besser ist als das schlechteste COBOL.
Radarbob