herança clássica vs herança prototípica em javascript

Pesquisei tantos links no Google e não consigo ter uma boa ideia sobre a diferença entre herança clássica e herança prototípica?

Aprendi algumas coisas com isto, mas ainda estou confuso sobre os conceitos.

herança clássica

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

a herança clássica usa a herança prototípica lá dentro?

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

de cima do link, aprendi que não podemos adicionar novos métodos no tempo de execução na herança clássica . Está correcto? Mas você pode verificar o código acima Eu posso adicionar o método "mover" e quaisquer métodos em tempo de execução através do protótipo. Então isto é uma herança clássica baseada em protótipos? Em caso afirmativo, o que é realmente clássico herança e protótipo de herança? Estou confuso com isso.

herança 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);
Isto é semelhante à herança clássica? Estou totalmente confuso sobre o que é a herança prototípica? O que é herança clássica? Porque é que a herança clássica é má?

Pode dar-me um exemplo simples para melhor compreendê-los de uma maneira simples?

Obrigado.

Siva

Author: Darush, 2013-10-28

2 answers

Ambas as amostras de código que demonstrou na sua pergunta fazem uso da herança prototípica. De fato, qualquer código orientado a objetos que você escreve em JavaScript é um paradigma de herança prototípica. JavaScript simplesmente não tem herança clássica. Isto deve esclarecer um pouco as coisas.

                                   Inheritance
                                        |
                         +-----------------------------+
                         |                             |
                         v                             v
                    Prototypal                     Classical
                         |
         +------------------------------+
         |                              |
         v                              v
Prototypal Pattern             Constructor Pattern
Como podem ver, a herança prototípica e a herança clássica são dois paradigmas diferentes da herança. Algumas línguas como Self, Lua e JavaScript suportam a herança prototípica. No entanto, a maioria das linguagens como C++, Java e C# suportam herança clássica.

Uma Visão geral rápida da Programação Orientada a objectos

Tanto a herança prototípica quanto a herança clássica são paradigmas de programação orientados a objetos (ou seja, lidam com objetos). Objetos são simplesmente abstrações que encapsulam as propriedades de uma entidade do mundo real (ou seja, eles representam coisas de palavras reais no programa). Isto é conhecido como abstração.

Abstracção: A representação de coisas do mundo real em programas de computador.

teoricamente uma abstração é definida como"um conceito geral formado pela extração de características comuns de exemplos específicos". No entanto, para o bem desta explicação, vamos usar a definição acima mencionada em vez disso.

Alguns objectos têm muitas coisas em comum. Por exemplo, uma bicicleta de lama e uma Harley Davidson têm muito em comum.

Uma lama bicicleta:

A mud bike.

Uma Harley Davidson:

A Harley Davidson

Uma bicicleta de lama e uma Harley Davidson são ambas bicicletas. Daí uma bicicleta é uma generalização de uma bicicleta de lama e uma Harley Davidson.
                   Bike
                     |
    +---------------------------------+
    |                                 |
    v                                 v
Mud Bike                       Harley Davidson
No exemplo acima, a bicicleta, a bicicleta de lama e a Harley Davidson são todas abstracções. No entanto, a moto é uma abstração mais geral da moto de lama e da Harley Davidson (ou seja, tanto a moto de lama e a Harley Davidson são tipos específicos de motos).

Generalização: uma abstração de uma abstração mais específica.

Em programação orientada a objetos criamos objetos (que são abstrações de entidades do mundo real) e usamos classes ou protótipos para criar generalizações desses objetos. Generalizações são criadas via herança. Uma bicicleta é uma generalização de uma bicicleta de lama. Daí as motos de lama herdarem das motos.


Programação Clássica Orientada A Objectos

Em programação clássica orientada a objetos temos dois tipos de abstrações: classes e objetos. Um objeto, como mencionado anteriormente, é uma abstração de uma entidade do mundo real. Uma classe, por outro lado, é uma abstração de um objeto ou outra classe (ou seja, é uma generalização). Por exemplo, 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 pode ver nas linguagens de programação clássicas orientadas a objectos, os objectos são apenas abstracções (isto é, todos os objectos têm um nível de abstracção de 1) e as classes são apenas generalizações (isto é, todas as classes têm um nível de abstração superior a 1).

Os objectos em linguagens de programação clássicas orientadas para objectos só podem ser criados por classes instanciadoras:

class Human {
    // ...
}

class Man extends Human {
    // ...
}

Man johnDoe = new Man();

Em suma, em linguagens de programação clássicas orientadas a objetos, objetos são abstrações de entidades do mundo real e classes são generalizações (ou seja, abstrações de objetos ou outras classes).

Por isso, à medida que o nível de abstracção aumenta, as entidades tornam-se mais gerais e, à medida que as o nível de abstração diminui as entidades tornam-se mais específicas. Neste sentido, o nível de abstração é análogo a uma escala que vai de entidades mais específicas a entidades mais gerais.

Programação Orientada A Objectos Prototipal

Linguagens de programação orientadas a objetos prototipais são muito mais simples do que linguagens de programação orientadas a objetos clássicas porque na programação orientada a objetos prototipais temos apenas um tipo de abstração (ou seja, objetos). Por exemplo, 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 pode ver em linguagens de programação orientadas a objetos prototipais, os objetos são abstrações de entidades do mundo real (nesse caso são simplesmente chamados objetos) ou outros objetos (nesse caso são chamados protótipos desses objetos que eles abstratam). Assim, um protótipo é uma generalização.

Objetos em linguagens de programação orientadas a objetos prototipais podem ser criados ou ex-nihilo (ou seja, fora do nada) ou a partir de outro objeto (que torna-se o protótipo do objeto recentemente criado):

var human = {};
var man = Object.create(human);
var johnDoe = Object.create(man);
Na minha humilde opinião, as linguagens de programação orientadas a objectos são mais poderosas do que as linguagens de programação orientadas a objectos clássicas porque:
    Só há um tipo de abstração.
  1. generalizações são simplesmente objectos.
Já deves ter percebido a diferença entre a herança clássica e a herança prototípica. A herança clássica está limitada a classes herdando de outras classes. No entanto, a herança prototípica inclui não só protótipos herdados de outros protótipos, mas também objetos herdados de protótipos.

Isomorfismo De Classe Protótipo

Deve ter reparado que os protótipos e as classes são muito semelhantes. É verdade. São. Na verdade, eles são tão semelhantes que você pode realmente usar protótipos para classes Modelo:
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 a função acima CLASS pode criar protótipos que se pareçam classes:

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

O inverso não é verdadeiro no entanto (ou seja, você não pode usar classes para modelar protótipos). Isto é porque protótipos são objetos, mas classes não são objetos. Eles são um tipo completamente diferente de abstração.


Conclusão

Em resumo, nós aprendemos que uma abstração, é um "um conceito formado por extração de características comuns a partir de exemplos específicos" e que a generalização é "uma abstração de um mais específico abstraction " . Também aprendemos sobre as diferenças entre a herança prototípica e clássica e como ambas são duas faces da mesma moeda.

Numa nota de despedida gostaria de observar que existem dois padrões de herança prototípica: o padrão prototípico e o padrão construtor. O padrão prototípico é o padrão canônico da herança prototípica, enquanto que o padrão construtor é usado para fazer a herança prototípica parecer mais clássica heranca. Pessoalmente, prefiro o padrão prototípico.

P. S. Eu sou o tipo que escreveu o post no blog " por que a herança prototípica importa" E respondeu à pergunta "benefícios da herança prototípica sobre a clássica?". A minha resposta é a resposta aceite.

 204
Author: Aadit M Shah, 2017-05-23 12:03:08

Antes de saltar para a herança, vamos dar uma olhada em doismodelos primários para criar instâncias (objetos) em javascript:

Modelo Clássico: o objecto é criado a partir de uma planta (classe)

class Person {
  fn() {...}
} // or constructor function say, function Person() {}

// create instance
let person = new Person();

Modelo Prototipal: o objecto é criado directamente a partir de outro objecto.

// base object
let Person = { fn(){...} }

// instance
let person = Object.create(Person);

Em ambos os casos, a herança* é obtida ligando objectos usando um protótipo de objecto.

(*os métodos da classe de base são acessíveis via. classe derivada através da prototype object and not required to be explicitly present in derived class.)

Aqui está uma boa explicação para entender melhor. http://www.objectplayground.com/)
 3
Author: everlasto, 2017-12-08 15:39:26