dziedziczenie Klasyczne a dziedziczenie prototypowe w javascript

Wygooglowałem tyle linków i nie mogę zrozumieć różnicy między dziedziczeniem klasycznym a dziedziczeniem prototypowym?

Nauczyłem się z nich pewnych rzeczy, ale nadal jestem zdezorientowany co do pojęć.

Dziedziczenie Klasyczne

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

Robi Klasyczne dziedziczenie użyj dziedziczenia prototypowego wewnątrz?

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

Z powyższego linku nauczyłem się nie możemy dodawać nowych metod w czasie wykonywania w klasycznym dziedziczeniu. Czy to prawda? Ale możesz sprawdzić powyższy kod Mogę dodać metodę "move" i dowolne metody w czasie wykonywania przez prototype . Więc to jest Klasyczne dziedziczenie oparte na prototypach? Jeśli tak, to czym jest rzeczywiste dziedziczenie klasyczne i prototyp spadek? Nie rozumiem tego.

Dziedziczenie prototypowe.

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

Czy jest to podobne do klasycznego dziedziczenia? Jestem całkowicie zdezorientowany co to jest dziedziczenie prototypowe? Czym jest dziedziczenie Klasyczne? Dlaczego Klasyczne dziedziczenie jest złe?

Czy możesz podać mi prosty przykład, aby lepiej je zrozumieć w prosty sposób?

Dzięki,

Siva

Author: Darush, 2013-10-28

2 answers

Oba przykłady kodu, które zademonstrowałeś w swoim pytaniu, wykorzystują dziedziczenie prototypowe. W rzeczywistości każdy kod obiektowy, który piszesz w JavaScript, jest paradygmatem dziedziczenia prototypowego. JavaScript po prostu nie ma klasycznego dziedziczenia. To powinno trochę wyjaśnić:

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

Jak widać dziedziczenie prototypowe i dziedziczenie Klasyczne to dwa różne paradygmaty dziedziczenia. Niektóre języki, takie jak Self, Lua i JavaScript, wspierają dziedziczenie prototypowe. Jednakże większość języków, takich jak C++, Java i C#, obsługuje dziedziczenie Klasyczne.


[[14]} szybki przegląd programowania obiektowego Zarówno dziedziczenie prototypowe, jak i dziedziczenie Klasyczne są obiektowymi paradygmatami programowania (tzn. zajmują się obiektami). Obiekty są po prostu abstrakcjami, które zawierają właściwości istoty świata rzeczywistego (tzn. reprezentują prawdziwe słowa w programie). Jest to znane jako abstrakcja.

Abstrakcja: The reprezentacja rzeczy świata rzeczywistego w programach komputerowych.

teoretycznie abstrakcję definiuje się jako "ogólne pojęcie utworzone przez wyodrębnienie cech wspólnych z konkretnych przykładów". Jednak ze względu na to Wyjaśnienie użyjemy powyższej definicji.

Teraz niektóre przedmioty mają wiele wspólnego. Na przykład rower błotny i Harley Davidson mają wiele wspólnego.

Błoto rower:

Rower błotny.

Harley Davidson:

Harley Davidson

Motocykl błotny i Harley Davidson to rowery. Stąd rower jest uogólnieniem zarówno błotnego roweru, jak i Harleya Davidsona.
                   Bike
                     |
    +---------------------------------+
    |                                 |
    v                                 v
Mud Bike                       Harley Davidson

W powyższym przykładzie rower, rower błotny i Harley Davidson są abstrakcjami. Jednak rower jest bardziej ogólna abstrakcja rower błotny i Harley Davidson (tj. zarówno rower błotny i Harley Davidson są specyficzne typy rowery).

Uogólnienie: abstrakcja bardziej specyficznej abstrakcji.

W programowaniu obiektowym tworzymy obiekty (które są abstrakcjami Bytów świata rzeczywistego) i używamy klas lub prototypów do tworzenia uogólnień tych obiektów. Uogólnienia są tworzone poprzez dziedziczenie. Rower jest uogólnieniem roweru błotnego. Stąd rowery błotne dziedziczą po rowerach.


Klasyczne Programowanie Obiektowe

W klasycznym programowanie obiektowe mamy dwa rodzaje abstrakcji: klasy i Obiekty. Obiekt, jak wspomniano wcześniej, jest abstrakcją bytu świata rzeczywistego. Klasa z drugiej strony jest abstrakcją obiektu lub innej klasy (tzn. jest uogólnieniem). Na przykład rozważmy:

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

Jak widać w klasycznych obiektowych językach programowania obiekty są tylko abstrakcjami (tzn. wszystkie obiekty mają poziom abstrakcji równy 1), A klasy są tylko uogólnieniami (tzn. wszystkie klasy mają poziom abstrakcji większy niż 1).

Obiekty w klasycznych obiektowych językach programowania mogą być tworzone tylko przez instancjonujące klasy:

class Human {
    // ...
}

class Man extends Human {
    // ...
}

Man johnDoe = new Man();

W sumowaniu w klasycznych obiektowych językach programowania obiekty są abstrakcjami Bytów świata rzeczywistego, A klasy są uogólnieniami (tj. abstrakcjami obiektów lub innych klas).

Stąd wraz ze wzrostem poziomu abstrakcji jednostki stają się bardziej ogólne i jako poziom abstrakcja zmniejsza byty stają się bardziej szczegółowe. W tym sensie poziom abstrakcji jest analogiczny do skali od bardziej szczegółowych podmiotów do bardziej ogólnych podmiotów.


Prototypowe Programowanie Obiektowe

Prototypowe języki programowania obiektowego są znacznie prostsze niż klasyczne, obiektowe języki programowania, ponieważ w prototypowym programowaniu obiektowym mamy tylko jeden rodzaj abstrakcji (tj. obiekty). Na przykład, consider:

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

Jak widać w prototypowych obiektowych językach programowania obiekty są abstrakcjami obiektów świata rzeczywistego (w tym przypadku są one po prostu nazywane obiektami) lub innych obiektów (w tym przypadku są nazywane prototypami tych obiektów, które abstrakcyjne). Stąd prototyp jest uogólnieniem.

Obiekty w prototypowych obiektowych językach programowania mogą być tworzone albo ex-nihilo (tzn. z niczego), albo z innego obiektu (który staje się prototyp nowo powstałego obiektu):

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

Moim skromnym zdaniem prototypowe, obiektowe języki programowania są potężniejsze od klasycznych, obiektowych języków programowania, ponieważ:]}

  1. istnieje tylko jeden rodzaj abstrakcji.
  2. uogólnienia są po prostu obiektami.

Do tej pory musiałeś zdać sobie sprawę z różnicy między dziedziczeniem klasycznym a dziedziczeniem prototypowym. Dziedziczenie Klasyczne jest ograniczone do klas dziedziczących z innych klas. Jednak dziedziczenie prototypowe obejmuje nie tylko prototypy dziedziczące z innych prototypów, ale także obiekty dziedziczące z prototypów.


Izomorfizm Klasy Prototypowej

Musiałeś zauważyć, że prototypy i klasy są bardzo podobne. To prawda. Są. W rzeczywistości są one tak podobne, że można użyć prototypów do modelowania klas: {]}

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

Za pomocą powyższej funkcji CLASS można tworzyć prototypy, które wyglądają jak klasy:

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

Odwrotność nie jest jednak prawdą (tzn. nie można używać klas do modelowania prototypów). Dzieje się tak, ponieważ prototypy są obiektami, ale klasy nie są obiektami. Są zupełnie innym rodzajem abstrakcji.


Podsumowanie

W podsumowaniu dowiedzieliśmy się, że abstrakcja jest "ogólnym pojęciem utworzonym przez wyodrębnienie wspólnych cech z konkretnych przykładów" i że uogólnienie jest "abstrakcją bardziej szczegółowego abstrakcja " . Dowiedzieliśmy się również o różnicach między dziedziczeniem prototypowym i klasycznym oraz o tym, że obie są dwiema twarzami tej samej monety.

Na pożegnanie chciałbym zauważyć, że istnieją dwa wzory dziedziczenia prototypowego: wzór prototypowy i wzór konstruktora. Wzór prototypowy jest kanonicznym wzorem dziedziczenia prototypowego, podczas gdy wzór konstruktora jest używany do tego, aby dziedziczenie prototypowe wyglądało bardziej jak klasyczne dziedziczenie. Osobiście wolę wzór prototypowy.

P. S. jestem facetem, który napisał post na blogu "dlaczego dziedziczenie prototypowe ma znaczenie "i odpowiedział na pytanie" korzyści dziedziczenia prototypowego nad klasycznym?". Moja odpowiedź jest akceptowana.

 204
Author: Aadit M Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:08

Zanim przejdziemy do dziedziczenia, przyjrzymy się dwóm podstawowym modelom do tworzenia instancji (obiektów) w javascript:

Model Klasyczny: obiekt jest tworzony z blueprint (class)

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

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

Model prototypowy: obiekt jest tworzony bezpośrednio z innego obiektu.

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

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

W obu przypadkach Dziedziczenie * jest osiągane przez łączenie obiektów za pomocą prototypowego obiektu.

(*metody klasy bazowej są dostępne poprzez. Klasa pochodna poprzez prototypowy obiekt i nie musi być jawnie obecny w klasie pochodnej.)

Tutaj jest dobre wyjaśnienie, aby lepiej zrozumieć ( http://www.objectplayground.com/)

 3
Author: everlasto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-08 15:39:26