multiple herencia es6 javascript inheritance

es6 - javascript herencia multiple



herencia clásica vs herencia prototípica en javascript (2)

He buscado tantos enlaces en Google y no puedo obtener una buena idea acerca de la diferencia entre la herencia clásica y la herencia prototípica.

He aprendido algunas cosas de estos pero todavía estoy confundido acerca de los conceptos.

Herencia clásica

// 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);

¿La herencia clásica usa herencia prototípica adentro?

http://aaditmshah.github.io/why-prototypal-inheritance-matters/

Desde el enlace anterior, aprendí que no podemos agregar nuevos métodos en tiempo de ejecución en la herencia clásica . ¿Es esto correcto? Pero puede verificar el código anterior. Puedo agregar el método "mover" y cualquier método en tiempo de ejecución a través del prototipo . Entonces, ¿esto es herencia clásica basada en prototipos? Si es así, ¿qué es la herencia clásica real y la herencia del prototipo? Estoy confundido acerca de eso.

Herencia prototípica

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

¿Es esto similar a la herencia clásica? Estoy totalmente confundido acerca de qué es la herencia prototípica? ¿Qué es la herencia clásica? ¿Por qué la herencia clásica es mala?

¿Puede darme un ejemplo simple para comprender mejor estos de una manera simple?

Gracias,

Siva


Antes de lanzarnos a la herencia, veremos dos modelos principales para crear instancias (objetos) en javascript:

Modelo clásico: el objeto se crea a partir de un plano (clase)

class Person { fn() {...} } // or constructor function say, function Person() {} // create instance let person = new Person();

Modelo Prototypal: el objeto se crea directamente desde otro objeto.

// base object let Person = { fn(){...} } // instance let person = Object.create(Person);

En cualquier caso, la herencia * se logra al vincular objetos usando objetos prototipo.

(* los métodos de clase base son accesibles a través de la clase derivada a través del objeto prototipo y no es necesario que estén explícitamente presentes en la clase derivada).

Aquí hay una buena explicación para comprender mejor ( http://www.objectplayground.com/ )


Las dos muestras de código que usted demostró en su pregunta hacen uso de la herencia prototípica. De hecho, cualquier código orientado a objetos que escriba en JavaScript es un paradigma de herencia prototípica. JavaScript simplemente no tiene herencia clásica. Esto debería aclarar un poco las cosas:

Inheritance | +-----------------------------+ | | v v Prototypal Classical | +------------------------------+ | | v v Prototypal Pattern Constructor Pattern

Como puede ver, la herencia prototípica y la herencia clásica son dos paradigmas diferentes de herencia. Algunos lenguajes como Self, Lua y JavaScript son compatibles con la herencia prototípica. Sin embargo, la mayoría de los lenguajes como C ++, Java y C # son compatibles con la herencia clásica.

Una descripción rápida de la programación orientada a objetos

Tanto la herencia prototípica como la herencia clásica son paradigmas de programación orientada a objetos (es decir, se ocupan de objetos). Los objetos son simplemente abstracciones que encapsulan las propiedades de una entidad del mundo real (es decir, representan cosas de palabras reales en el programa). Esto se conoce como abstracción.

Abstracción: la representación de cosas del mundo real en programas de computadora.

Teóricamente, una abstracción se define como "un concepto general formado por la extracción de características comunes a partir de ejemplos específicos". Sin embargo, por el bien de esta explicación, vamos a utilizar la definición mencionada anteriormente.

Ahora, algunos objetos tienen muchas cosas en común. Por ejemplo, una bicicleta de barro y una Harley Davidson tienen mucho en común.

Una bicicleta de barro:

Una Harley Davidson:

Una bicicleta de barro y una Harley Davidson son motos. Por lo tanto, una bicicleta es una generalización de una bicicleta de barro y una Harley Davidson.

Bike | +---------------------------------+ | | v v Mud Bike Harley Davidson

En el ejemplo anterior, la bicicleta, la moto de barro y la Harley Davidson son abstracciones. Sin embargo, la bicicleta es una abstracción más general de la bicicleta de barro y la Harley Davidson (es decir, tanto la bicicleta de barro como la Harley Davidson son tipos específicos de bicicletas).

Generalización: una abstracción de una abstracción más específica.

En la programación orientada a objetos, creamos objetos (que son abstracciones de entidades del mundo real) y utilizamos clases o prototipos para crear generalizaciones de estos objetos. Las generalizaciones se crean a través de la herencia. Una bicicleta es una generalización de una bicicleta de barro. Por lo tanto, las bicicletas de barro heredan de las bicicletas.

Programación orientada a objetos clásica

En la programación clásica orientada a objetos, tenemos dos tipos de abstracciones: clases y objetos. Un objeto, como se mencionó antes, es una abstracción de una entidad del mundo real. Una clase por otro lado es una abstracción de un objeto u otra clase (es decir, es una generalización). Por ejemplo, considere:

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

Como puede ver en los lenguajes de programación orientados a objetos clásicos, los objetos son solo abstracciones (es decir, todos los objetos tienen un nivel de abstracción de 1) y las clases son solo generalizaciones (es decir, todas las clases tienen un nivel de abstracción mayor que 1).

Los objetos en lenguajes de programación orientados a objetos clásicos solo se pueden crear instanciando clases:

class Human { // ... } class Man extends Human { // ... } Man johnDoe = new Man();

En resumen, en los lenguajes de programación orientados a objetos clásicos, los objetos son abstracciones de entidades del mundo real y las clases son generalizaciones (es decir, abstracciones de cualquiera de los objetos u otras clases).

Por lo tanto, a medida que el nivel de abstracción aumenta, las entidades se vuelven más generales y, a medida que el nivel de abstracción disminuye, las entidades se vuelven más específicas. En este sentido, el nivel de abstracción es análogo a una escala que va desde entidades más específicas a entidades más generales.

Programación Prototypal Orientada a Objetos

Los lenguajes de programación orientados a objetos prototípicos son mucho más simples que los lenguajes de programación orientados a objetos clásicos porque en la programación orientada a objetos prototípica solo tenemos un tipo de abstracción (es decir, objetos). Por ejemplo, considere:

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

Como puede ver en los lenguajes de programación prototípicos orientados a objetos, los objetos son abstracciones de entidades del mundo real (en cuyo caso simplemente se llaman objetos) u otros objetos (en cuyo caso se llaman prototipos de aquellos objetos que abstraen). Por lo tanto, un prototipo es una generalización.

Los objetos en lenguajes de programación orientados a objetos prototípicos se pueden crear ya sea ex-nihilo (es decir, de la nada) o desde otro objeto (que se convierte en el prototipo del objeto recién creado):

var human = {}; var man = Object.create(human); var johnDoe = Object.create(man);

En mi humilde opinión, los lenguajes de programación orientados a objetos prototípicos son más potentes que los lenguajes de programación orientados a objetos clásicos porque:

  1. Solo hay un tipo de abstraccion.
  2. Las generalizaciones son simplemente objetos.

A estas alturas debe haberse dado cuenta de la diferencia entre la herencia clásica y la herencia prototípica. La herencia clásica está limitada a las clases heredadas de otras clases. Sin embargo, la herencia prototípica incluye no solo prototipos que heredan de otros prototipos sino también objetos que heredan de prototipos.

Isomorfismo de clase prototipo

Debes haber notado que los prototipos y las clases son muy similares. Es verdad. Son. De hecho, son tan similares que puedes usar prototipos para modelar clases:

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; } }

Usando la función CLASS anterior, puede crear prototipos que se parecen a las clases:

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

Sin embargo, lo contrario no es cierto (es decir, no puede usar clases para modelar prototipos). Esto se debe a que los prototipos son objetos, pero las clases no son objetos. Son un tipo de abstracción completamente diferente.

Conclusión

En resumen, aprendimos que una abstracción es un "concepto general formado al extraer características comunes de ejemplos específicos" y que la generalización es "una abstracción de una abstracción más específica" . También aprendimos sobre las diferencias entre herencia prototípica y clásica y cómo ambas son dos caras de la misma moneda.

En una nota de despedida, me gustaría señalar que hay dos patrones de herencia prototípica: el patrón prototípico y el patrón constructor. El patrón prototípico es el patrón canónico de la herencia prototípica, mientras que el patrón constructor se utiliza para hacer que la herencia prototípica se parezca más a la herencia clásica. Personalmente prefiero el patrón prototípico.

PD. Soy el tipo que escribió la publicación del blog " http://aaditmshah.github.io/why-prototypal-inheritance-matters/ " Y respondí a la pregunta "¿ Beneficios de la herencia prototípica sobre la clásica? ". Mi respuesta es la respuesta aceptada.