Ich habe so viele Links gegoogelt und kann keine gute Vorstellung vom Unterschied zwischen klassischer Vererbung und prototypischer Vererbung bekommen?
Ich habe einige Dinge daraus gelernt, bin aber immer noch verwirrt über die Konzepte.
Vorteile der prototypischen Vererbung gegenüber der klassischen?
http://aaditmshah.github.io/why-prototypal-inheritance-matters/
Klassische Vererbung
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
//superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); //call super constructor.
}
//subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Verwendet die klassische Vererbung die prototypische Vererbung im Inneren?
http://aaditmshah.github.io/why-prototypal-inheritance-matters/
Durch den obigen Link habe ich erfahren, dass wir zur Laufzeit keine neuen Methoden für die klassische Vererbung hinzufügen können . Ist das richtig? Sie können jedoch den obigen Code überprüfen. Ich kann die "move" -Methode und alle Methoden zur Laufzeit über den Prototyp hinzufügen . Das ist also eine prototypbasierte klassische Vererbung? Wenn ja, was ist die tatsächliche klassische Vererbung und die Prototypvererbung? Das verwirrt mich.
Prototypische Vererbung.
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.area = function () {
var radius = this.radius;
return Math.PI * radius * radius;
};
Circle.prototype.circumference: function () {
return 2 * Math.PI * this.radius;
};
var circle = new Circle(5);
var circle2 = new Circle(10);
Ist das ähnlich wie bei der klassischen Vererbung? Ich bin total verwirrt darüber, was prototypische Vererbung ist. Was ist klassisches Erbe? Warum ist klassisches Erbe schlecht?
Können Sie mir ein einfaches Beispiel geben, um diese auf einfache Weise besser zu verstehen?
Vielen Dank,
Siva
quelle
Antworten:
Beide Codebeispiele, die Sie in Ihrer Frage demonstriert haben, verwenden die prototypische Vererbung. Tatsächlich ist jeder objektorientierte Code, den Sie in JavaScript schreiben, ein Paradigma der prototypischen Vererbung. JavaScript hat einfach keine klassische Vererbung. Dies sollte die Dinge ein wenig aufklären:
Wie Sie sehen können, sind prototypische Vererbung und klassische Vererbung zwei verschiedene Paradigmen der Vererbung. Einige Sprachen wie Self, Lua und JavaScript unterstützen die prototypische Vererbung. Die meisten Sprachen wie C ++, Java und C # unterstützen jedoch die klassische Vererbung.
Ein kurzer Überblick über die objektorientierte Programmierung
Sowohl die prototypische Vererbung als auch die klassische Vererbung sind objektorientierte Programmierparadigmen (dh sie befassen sich mit Objekten). Objekte sind einfach Abstraktionen, die die Eigenschaften einer realen Entität einschließen (dh sie repräsentieren reale Wortsachen im Programm). Dies ist als Abstraktion bekannt.
Abstraktion: Die Darstellung realer Dinge in Computerprogrammen.
Theoretisch wird eine Abstraktion definiert als "ein allgemeines Konzept, das durch Extrahieren gemeinsamer Merkmale aus bestimmten Beispielen gebildet wird". Für diese Erklärung werden wir jedoch stattdessen die oben genannte Definition verwenden.
Jetzt haben einige Objekte viele Gemeinsamkeiten. Zum Beispiel haben ein Schlammrad und eine Harley Davidson viel gemeinsam.
Ein Schlammrad:
Eine Harley Davidson:
Ein Schlammrad und eine Harley Davidson sind beide Fahrräder. Daher ist ein Fahrrad eine Verallgemeinerung sowohl eines Schlammrads als auch einer Harley Davidson.
Im obigen Beispiel sind das Fahrrad, das Schlammrad und die Harley Davidson Abstraktionen. Das Fahrrad ist jedoch eine allgemeinere Abstraktion des Schlammfahrrads und der Harley Davidson (dh sowohl das Schlammfahrrad als auch die Harley Davidson sind bestimmte Arten von Fahrrädern).
Generalisierung: Eine Abstraktion einer spezifischeren Abstraktion.
In der objektorientierten Programmierung erstellen wir Objekte (die Abstraktionen realer Entitäten sind) und verwenden entweder Klassen oder Prototypen, um Verallgemeinerungen dieser Objekte zu erstellen. Verallgemeinerungen werden durch Vererbung erstellt. Ein Fahrrad ist eine Verallgemeinerung eines Schlammfahrrads. Daher erben Schlammfahrräder von Fahrrädern.
Klassische objektorientierte Programmierung
In der klassischen objektorientierten Programmierung gibt es zwei Arten von Abstraktionen: Klassen und Objekte. Ein Objekt ist, wie bereits erwähnt, eine Abstraktion einer realen Entität. Eine Klasse hingegen ist eine Abstraktion eines Objekts oder einer anderen Klasse (dh eine Verallgemeinerung). Betrachten Sie zum Beispiel:
Wie Sie in klassischen objektorientierten Programmiersprachen sehen können, sind Objekte nur Abstraktionen (dh alle Objekte haben eine Abstraktionsstufe von 1) und Klassen sind nur Verallgemeinerungen (dh alle Klassen haben eine Abstraktionsstufe größer als 1).
Objekte in klassischen objektorientierten Programmiersprachen können nur durch Instanziieren von Klassen erstellt werden:
In klassischen objektorientierten Programmiersprachen sind Objekte Abstraktionen realer Entitäten und Klassen Verallgemeinerungen (dh Abstraktionen von Objekten oder anderen Klassen).
Daher werden Entitäten mit zunehmender Abstraktionsebene allgemeiner und mit abnehmender Abstraktionsebene Entitäten spezifischer. In diesem Sinne ist die Abstraktionsebene analog zu einer Skala, die von spezifischeren Entitäten bis zu allgemeineren Entitäten reicht.
Prototypische objektorientierte Programmierung
Prototypische objektorientierte Programmiersprachen sind viel einfacher als klassische objektorientierte Programmiersprachen, da wir in der prototypischen objektorientierten Programmierung nur einen Abstraktionstyp (dh Objekte) haben. Betrachten Sie zum Beispiel:
Wie Sie in prototypischen objektorientierten Programmiersprachen sehen können, sind Objekte Abstraktionen von Entitäten der realen Welt (in diesem Fall werden sie einfach als Objekte bezeichnet) oder anderen Objekten (in diesem Fall werden sie als Prototypen der Objekte bezeichnet, die sie abstrahieren). Ein Prototyp ist also eine Verallgemeinerung.
Objekte in prototypischen objektorientierten Programmiersprachen können entweder ex-nihilo (dh aus dem Nichts) oder aus einem anderen Objekt (das zum Prototyp des neu erstellten Objekts wird) erstellt werden:
Meiner bescheidenen Meinung nach sind prototypische objektorientierte Programmiersprachen leistungsfähiger als klassische objektorientierte Programmiersprachen, weil:
Inzwischen müssen Sie den Unterschied zwischen klassischer Vererbung und prototypischer Vererbung erkannt haben. Die klassische Vererbung ist auf Klassen beschränkt, die von anderen Klassen erben. Die prototypische Vererbung umfasst jedoch nicht nur Prototypen, die von anderen Prototypen erben, sondern auch Objekte, die von Prototypen erben.
Isomorphismus der Prototypklasse
Sie müssen bemerkt haben, dass Prototypen und Klassen sehr ähnlich sind. Das ist richtig. Sie sind. Tatsächlich sind sie sich so ähnlich, dass Sie tatsächlich Prototypen verwenden können, um Klassen zu modellieren:
Mit der obigen
CLASS
Funktion können Sie Prototypen erstellen, die wie Klassen aussehen:Das Gegenteil ist jedoch nicht der Fall (dh Sie können keine Klassen zum Modellieren von Prototypen verwenden). Dies liegt daran, dass Prototypen Objekte sind, Klassen jedoch keine Objekte. Sie sind eine ganz andere Art der Abstraktion.
Fazit
Zusammenfassend haben wir gelernt, dass eine Abstraktion ein "allgemeines Konzept ist, das durch Extrahieren gemeinsamer Merkmale aus bestimmten Beispielen gebildet wird", und dass die Verallgemeinerung "eine Abstraktion einer spezifischeren Abstraktion" ist . Wir haben auch die Unterschiede zwischen prototypischer und klassischer Vererbung kennengelernt und erfahren, wie beide zwei Gesichter derselben Medaille sind.
Zum Abschied möchte ich bemerken, dass es zwei Muster der prototypischen Vererbung gibt: das prototypische Muster und das Konstruktormuster. Das prototypische Muster ist das kanonische Muster der prototypischen Vererbung, während das Konstruktormuster verwendet wird, um die prototypische Vererbung eher wie die klassische Vererbung aussehen zu lassen. Persönlich bevorzuge ich das prototypische Muster.
PS Ich bin der Typ, der den Blog-Beitrag " Why Prototypal Inheritance Matters " geschrieben und die Frage " Vorteile der prototypischen Vererbung gegenüber der klassischen? " Beantwortet hat . Meine Antwort ist die akzeptierte Antwort.
quelle
programming with classes = classical inheritance
,programming with prototypes = prototypal inheritance
,programming with constructors = weird form of prototypal inheritance that looks a lot like classical inheritance
. Hoffe das klärt die Dinge.Bevor wir uns mit der Vererbung befassen, werden wir uns zwei Hauptmodelle ansehen , um Instanzen (Objekte) in Javascript zu erstellen:
Klassisches Modell: Das Objekt wird aus einer Blaupause (Klasse) erstellt.
Prototypisches Modell: Das Objekt wird direkt aus einem anderen Objekt erstellt.
In beiden Fällen wird die Vererbung * durch Verknüpfen von Objekten mithilfe eines Prototypobjekts erreicht.
(* Basisklassenmethoden sind über die abgeleitete Klasse über das Prototypobjekt zugänglich und müssen in der abgeleiteten Klasse nicht explizit vorhanden sein.)
Hier ist eine gute Erklärung, um besser zu verstehen ( http://www.objectplayground.com/ )
quelle
Ein Hund ist ein Tier. Suzanna ist ein Hund. In der klassischen Vererbung
Animal
ist eine Klasse,Dog
ist eine Unterklasse vonAnimal
undsuzanna
ist eine Instanz von aDog
.Bei der prototypischen Vererbung gibt es keine Klasse. Sie haben eine
animal
, die ein Objekt ist. Adog
ist ein anderes Objekt, das klont und erweitertanimal
(das Prototypobjekt).suzanna
ist ein drittes Objekt, das kopiert und erweitertdog
.Wenn Sie schreiben ,
Dog
stattdog
, vor allem , wenn Sie machenDog
eine Art von „Konstruktor“ -Funktion, dann tun Sie nicht prototypische Vererbung; Sie machen (pseudo-) klassische Vererbung . Die Tatsache, dass SieObject.create()
dies verwenden, bedeutet nicht, dass Sie eine prototypische Vererbung durchführen.Tatsächlich unterstützt JavaScript nur die prototypische Vererbung. Der verwirrende
new
Operator und das verwirrende.prototype
Attribut sind vorhanden, damit die prototypische Vererbung wie eine (pseudo-) klassische Vererbung aussieht.Douglas Crockford untersucht dies ausführlich in seinem Buch "JavaScript: The Good Parts".
quelle