Gibt es OO-Sprachen ohne Vererbung?

22

Während einer Codeüberprüfung sagte heute ein Kollege von mir etwas Interessantes:

prototypeist nur nützlich, wenn Sie Vererbung benötigen - und wann ist Vererbung jemals eine gute Idee ?

Ich habe darüber nachgedacht und festgestellt, dass ich normalerweise Vererbung verwende, um Code zu umgehen, der von Anfang an schlecht entworfen wurde. Der moderne OO-Stil zieht die Komposition der Vererbung vor, aber ich kenne keine Sprachen, die sich das zu Herzen genommen und es tatsächlich durchgesetzt haben.

Gibt es universelle Programmiersprachen mit Klassen, Objekten, Methoden, Schnittstellen usw., die eine klassenbasierte Vererbung nicht zulassen? (Wenn eine solche Idee keinen Sinn ergibt, warum nicht?)

Benjamin Hodgson
quelle
7
Ihr Kollege hat Sie in die Irre geführt. Dies prototypeist auch nützlich, wenn Sie über öffentliche Methoden und Eigenschaften verfügen, die von Instanzen gemeinsam genutzt werden sollen. Es ist auch nützlich , weil es Ihnen richtig die verwenden instanceofOperator in JavaScript: if (foo instanceof Foo) { ....
Greg Burghardt
2
Ich denke, wir sollten zwischen der Vererbung von Typ, Zustand und Verhalten unterscheiden. Die Bevorzugung der Komposition ist in der Java-Community weit verbreitet, aber gleichzeitig wird die Vererbung (und sogar die Mehrfachvererbung) von Typen häufig verwendet und gefördert ... und mithilfe des implementsSchlüsselworts und der Schnittstellen (im Gegensatz zur Vererbung von state und Verhalten, das mit der Verwendung des extendsSchlüsselworts für Klassen eingeführt wurde, die eine Implementierung enthalten).
Toniedzwiedz
6
Komposition zu bevorzugen, bedeutet nicht, die Vererbung ganz aufzugeben, ist eine gute Idee.
Caleb
5
siehe Java ohne Implementierungsvererbung : „ Die Google-go ist ein Beispiel für eine Sprache , die mit der Umsetzung Vererbung beseitigt , während OOP zu sein ...“
gnat
1
@GregBurghardt Dasselbe kann mit einer Factory-Funktion erreicht werden, die ein Objekt zurückgibt, das Funktionen enthält (private Daten im Closure speichern). new, thisund prototypesind ein allzu großes Minenfeld für die gemeinsame Nutzung IMO.
Benjamin Hodgson

Antworten:

18

Abgesehen von der Frage nach der Definition der objektorientierten Programmierung stellt sich die Frage: "Gibt es Sprachen, die nur die Komposition verwenden und keine Vererbungswerkzeuge haben?"

Die Antwort darauf lautet ganz einfach "Ja". In Go gibt es keine Möglichkeit, Vererbung zu betreiben, wie man es klassisch denkt. Man kann ein Objekt in ein anderes Objekt einbetten und das Objekt erweitern. Aus der objektorientierten Sprache ( Github-Spiegel ):

type Person struct {
        Name string
}

func (p *Person) Intro() string {
        return p.Name
}

type Woman struct {
        Person
}

func (w *Woman) Intro() string {
        return "Mrs. " + w.Person.Intro()
}

Sie haben eine Personenstruktur mit einem Namen, der eine Zeichenfolge ist. Es hat eine öffentliche Funktion namens Intro, die den Namen zurückgibt. Die Woman-Struktur hat auch eine Intro-Funktion, die auf die darin eingebettete Strebe zugreift. Und so kann man die Absichten der Vererbung nur mit Komposition erfüllen.

Weitere Informationen hierzu finden Sie in den GoLang-Tutorials: Vererbung und Unterklassen in Go - oder seine Ähnlichkeit .

Also ja, es ist möglich, eine OO-Sprache ohne Vererbung zu haben, und eine existiert.

Innerhalb von go wird dies als Einbettung bezeichnet und ermöglicht es umschließenden Strukturen, auf die eingebetteten Felder zuzugreifen und zu funktionieren, als ob sie diese auch hätten - dies ist jedoch keine Unterklasse. Die Designphilosophie finden Sie in den Go-FAQ: Warum gibt es keine Typvererbung?


quelle
Man könnte auch über die Verwendung von typedefund structin C ...
Cwallenpoole
@cwallenpoole es gibt in der Tat ähnliche Ideen, obwohl ich zögern würde, C eine objektorientierte Sprache zu nennen.
Ich weiß nicht. Ich gebe zu, dass Sie keine Objekte mit angehängten Funktionen erstellen können, aber ohne Vererbung verliert OOP einen Großteil seines Geschmacks.
Cwallenpoole
@cwallenpoole und wir beginnen mit der Definition von Vererbung und Objektorientierung. Aber es ist möglich, es ist nur eine andere Art, über das Problem nachzudenken. Die Sache ist, dass Vererbung die Art und Weise ist, wie die meisten C ++ - und Java-Programmierer Erweiterungen betrachten ... aber es gibt andere Modelle. Erweiterung ohne Vererbung: 1 , 2 , 3 sind gute Lesevorgänge.
Der Link zu "Object Desoriented Language" steckt momentan in einer Umleitungsschleife, aber ich habe den Artikel hier gefunden: github.com/nu7hatch/areyoufuckingcoding.me/blob/master/content/… . Vielen Dank!
Matt Browne
7

Gibt es universelle Programmiersprachen mit Klassen, Objekten, Methoden, Schnittstellen usw., die eine klassenbasierte Vererbung nicht zulassen?

Dies ähnelt einer Beschreibung von VBA - Visual Basic für Applikationen, eingebettet in Microsoft Office und andere VBA-fähige Hosts (z. B. AutoCAD, Sage 300 ERP usw.) oder sogar VB6. Das "A" von "Basic" steht sowieso für "Allzweck", also gibt es den Teil "Allzweck".

VB6 / VBA verfügt über Klassen (und damit Objekte), Methoden und Schnittstellen. Sie können eine ISomethingSchnittstelle in einem Klassenmodul wie folgt definieren:

Option Explicit

Public Sub DoSomething()
End Sub

Und dann noch eine Klasse, die das macht:

Option Explicit
Implements ISomething

Private Sub ISomething_DoSomething()
    'implementation here
End Sub

Auf eine solche Klasse, die keine öffentlichen Mitglieder enthüllt, konnte nur über ihre ISomethingSchnittstelle zugegriffen werden - und es könnte sehr wohl Dutzende verschiedener Implementierungen ISomethinggeben, so dass OOP-VBA-Code durchaus polymorph sein kann und für eine bestimmte Klasse vollkommen legal ist auch mehrere Schnittstellen zu implementieren.

VB6 / VBA lässt jedoch keine Klassenvererbung zu , sodass Sie eine Implementierung nicht von einem anderen Typ erben können, sondern nur von dessen Schnittstelle. Ob es sich nun um einen Unfall, einen Konstruktionsfehler, einen Geniestreich oder ein großes hässliches Versehen handelt, steht zur Debatte. Es ist nicht klar, ob VB6 / VBA dies zu Herzen nimmt , aber es erzwingt es auf jeden Fall .

Wenn Go keine Klassenvererbung durchführt und dennoch eine OOP-Sprache ist , kann ich nicht nachvollziehen, warum VB6 / VBA nicht auch als OOP-Sprache angesehen werden kann.</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>

Mathieu Guindon
quelle
1
Um fair zu sein, fragte OP nach modernen Sprachen. =;) -
RubberDuck
@RubberDuck #burn!
Mathieu Guindon
0

Sie können den Compiler veranlassen, selektive Vererbung durch die Verwendung von privat / geschützt und durch die moderne Verwendung von "PImpl" - oder "Private Implementation" -Techniken zu erzwingen.

Viele APIs stellen nur die Komponenten bereit, die ein Benutzer erben soll, und verbergen den Rest in einer separaten Implementierungsklasse. Sie können also Klassen schreiben, deren öffentliche Schnittstellen tatsächlich nicht vererbbar, nur durch die Objektzusammensetzung verwendbar und vom Compiler erzwungen sind. Dies ist häufig eine gute Praxis, wenn der Compiler verwendet wird, um die Absicht der Software durchzusetzen.

Eine schnelle Suche nach Funktionen für private Mitglieder in Javascript zeigt, dass es ein ähnliches Prinzip gibt, obwohl jeder Ihren Code sehen kann, wenn er ihn verwenden kann: http://www.crockford.com/javascript/private.html

Ruan Caiman
quelle