Entrambi gli esempi di codice che si dimostrò nella sua interrogazione fare uso di ereditarietà prototipale. In effetti qualsiasi codice orientato agli oggetti che scrivi in JavaScript è un paradigma dell'ereditarietà prototipale. JavaScript semplicemente non ha ereditarietà classica. Questo dovrebbe chiarire le cose un po ':
Inheritance
|
+-----------------------------+
| |
v v
Prototypal Classical
|
+------------------------------+
| |
v v
Prototypal Pattern Constructor Pattern
Come si può vedere l'ereditarietà prototipale e l'eredità classica sono due diversi paradigmi di ereditarietà. Alcuni linguaggi come Self, Lua e JavaScript supportano l'ereditarietà prototipale. Tuttavia la maggior parte delle lingue come C++, Java e C# supportano l'ereditarietà classica.
Una veloce Panoramica dei
Sia ereditarietà prototipale programmazione orientata agli oggetti e di eredità classica sono paradigmi di programmazione orientata agli oggetti (cioè hanno a che fare con gli oggetti). Gli oggetti sono semplicemente astrazioni che incapsulano le proprietà di un'entità del mondo reale (cioè rappresentano le parole reali nel programma). Questo è noto come astrazione.
Astrazione: La rappresentazione di cose del mondo reale nei programmi per computer.
In teoria un'astrazione viene definita come "un concetto generale formato estraendo caratteristiche comuni da esempi specifici". Tuttavia, per il gusto di questa spiegazione, utilizzeremo invece la definizione sopra menzionata.
Ora alcuni oggetti hanno molte cose in comune. Ad esempio una bici da fango e una Harley Davidson hanno molto in comune.
Una moto di fango:
una Harley Davidson:
Una moto fango e una Harley Davidson sono entrambe le moto. Quindi una bici è una generalizzazione sia di una moto da fango che di una Harley Davidson.
Bike
|
+---------------------------------+
| |
v v
Mud Bike Harley Davidson
Nell'esempio precedente la bicicletta, la bici da fango e l'Harley Davidson sono tutte astrazioni. Tuttavia, la bici è un'astrazione più generale della moto da fango e della Harley Davidson (vale a dire sia la moto da fango che l'Harley Davidson sono tipi specifici di bici).
Generalizzazione: Un'astrazione di un'astrazione più specifica.
Nella programmazione orientata agli oggetti creiamo oggetti (che sono astrazioni di entità del mondo reale) e usiamo le classi oi prototipi per creare generalizzazioni di questi oggetti. Le generalizzazioni sono create tramite l'ereditarietà. Una bici è una generalizzazione di una bici da fango. Quindi le bici da fango ereditano dalle biciclette.
classica programmazione orientata agli oggetti
Nella programmazione orientata agli oggetti classica abbiamo due tipi di astrazioni: classi e oggetti. Un oggetto, come accennato prima, è un'astrazione di un'entità del mondo reale. D'altra parte, una classe è un'astrazione di un oggetto o di un'altra classe (cioè è una generalizzazione). Ad esempio, si consideri:
+----------------------+----------------+---------------------------------------+
| Level of Abstraction | Name of Entity | Comments |
+----------------------+----------------+---------------------------------------+
| 0 | John Doe | Real World Entity. |
| 1 | johnDoe | Variable holding object. |
| 2 | Man | Class of object johnDoe. |
| 3 | Human | Superclass of class Man. |
+----------------------+----------------+---------------------------------------+
Come si può vedere nei linguaggi di programmazione orientati agli oggetti classici oggetti sono solo astrazioni (vale a dire tutti gli oggetti hanno un livello di astrazione di 1) e le classi sono solo generalizzazioni (vale a dire tutte le classi hanno un'astrazione livello superiore a 1).
oggetti nei linguaggi di programmazione orientati agli oggetti classici possono essere creati solo da Istanziare classi:
class Human {
// ...
}
class Man extends Human {
// ...
}
Man johnDoe = new Man();
In somma nei linguaggi di programmazione orientati agli oggetti classici oggetti sono astrazioni di entità del mondo reale e le classi sono generalizzazioni (cioè astrazioni di entrambi gli oggetti o altre classi).
Di conseguenza, quando il livello di astrazione aumenta, le entità diventano più generali e man mano che il livello di astrazione diminuisce, le entità diventano più specifiche. In questo senso il livello di astrazione è analogo a una scala che va da entità più specifiche a entità più generali.
prototipale Object-Oriented Programming
prototipale linguaggi di programmazione orientati agli oggetti sono molto più semplici di linguaggi di programmazione orientati agli oggetti classici, perché in programmazione orientata agli oggetti prototipale abbiamo un solo tipo di astrazione (cioè gli oggetti) . Ad esempio, si consideri:
+----------------------+----------------+---------------------------------------+
| Level of Abstraction | Name of Entity | Comments |
+----------------------+----------------+---------------------------------------+
| 0 | John Doe | Real World Entity. |
| 1 | johnDoe | Variable holding object. |
| 2 | man | Prototype of object johnDoe. |
| 3 | human | Prototype of object man. |
+----------------------+----------------+---------------------------------------+
Come si può vedere nei linguaggi prototipali programmazione orientata agli oggetti Gli oggetti sono astrazioni di un'entità del mondo reale (nel qual caso essi sono semplicemente chiamati oggetti) o altri oggetti (nel qual caso essi sono chiamati prototipi di quegli oggetti che astraggono). Quindi un prototipo è una generalizzazione.
oggetti nei linguaggi di programmazione orientati agli oggetti prototipali possono essere creati sia ex-nihilo (cioè dal nulla), o da un altro oggetto (che diventa il prototipo del nuovo oggetto creato):
var human = {};
var man = Object.create(human);
var johnDoe = Object.create(man);
Nella mia humble opinion prototypal linguaggi di programmazione orientati agli oggetti sono più potenti dei classici linguaggi di programmazione orientati agli oggetti perché:
- C'è un solo tipo di astrazione.
- Le generalizzazioni sono semplicemente oggetti.
Ormai è necessario aver compreso la differenza tra ereditarietà classica e eredità prototipale. L'ereditarietà classica è limitata alle classi che ereditano da altre classi. Tuttavia, l'ereditarietà prototipale include non solo i prototipi che ereditano da altri prototipi, ma anche oggetti che ereditano dai prototipi.
Prototype-Class Isomorfismo
Avrai notato che i prototipi e le classi sono molto simili. È vero. Loro sono. In realtà essi sono così simili che si può effettivamente utilizzare prototipi per modellare le classi:
function CLASS(base, body) {
if (arguments.length < 2) body = base, base = Object.prototype;
var prototype = Object.create(base, {new: {value: create}});
return body.call(prototype, base), prototype;
function create() {
var self = Object.create(prototype);
return prototype.hasOwnProperty("constructor") &&
prototype.constructor.apply(self, arguments), self;
}
}
Utilizzando la funzione di cui sopra CLASS
è possibile creare prototipi che assomigliano a classi:
var Human = CLASS(function() {
var milliseconds = 1
, seconds = 1000 * milliseconds
, minutes = 60 * seconds
, hours = 60 * minutes
, days = 24 * hours
, years = 365.2425 * days;
this.constructor = function (name, sex, dob) {
this.name = name;
this.sex = sex;
this.dob = dob;
};
this.age = function() {
return Math.floor((new Date - this.dob)/years);
};
});
var Man = CLASS(Human, function (Human) {
this.constructor = function (name, dob) {
Human.constructor.call(this, name, "male", dob);
if (this.age() < 18) throw new Error(name + " is a boy, not a man!");
};
});
var johnDoe = Man.new("John Doe", new Date(1970, 0, 1));
il contrario non è vero, però (cioè non puoi usare le classi per modellare i prototipi). Questo perché i prototipi sono oggetti ma le classi non sono oggetti. Sono un tipo completamente diverso di astrazione.
Conclusione
Riassumendo abbiamo appreso che un astrazione è un "un concetto generale formata da estrazione di caratteristiche comuni da esempi specifici" e che generalizzazione è "un'astrazione di un'astrazione più specifico".Abbiamo anche appreso le differenze tra l'ereditarietà prototipale e classica e in che modo entrambi sono due facce della stessa medaglia.
In una nota di separazione vorrei sottolineare che esistono due modelli di ereditarietà prototipale: il modello prototipo e il modello di costruzione. Il modello prototipo è il modello canonico dell'ereditarietà prototipale mentre il modello del costruttore viene utilizzato per rendere l'ereditarietà prototipale più simile all'ereditarietà classica. Personalmente preferisco il modello prototipo.
P.S. Sono il ragazzo che ha scritto il post sul blog "Why Prototypal Inheritance Matters" e ha risposto alla domanda "Benefits of prototypal inheritance over classical?". La mia risposta è la risposta accettata.
duplicati , guarda questo: http://stackoverflow.com/questions/1595611/how-to-properly-create-a-custom-object-in-javascript/1598077#1598077 –
non sai di cosa stai parlando - il primo blocco di codice _is_ l'eredità prototipica, non classica. Il tuo secondo blocco di codice non ha alcuna eredità! – Alnitak
Questo può xplain: http://blog.stephenwyattbush.com/2012/05/01/comparing-prototypal-and-classical-inheritance – HasanAboShally