классическое наследование против прототипного наследования в JavaScript
я погуглил так много ссылок и не могу получить хорошее представление о разнице между классическим наследованием и прототипным наследованием?
я узнал некоторые вещи из них, но я все еще запутался в понятиях.
классическое наследование
// 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);
использует ли классическое наследование прототипное наследование внутри?
http://aaditmshah.github.io/why-prototypal-inheritance-matters/
из ссылки выше, я узнал мы не можем добавлять новые методы во время выполнения в классическое наследование. Это правильно? Но вы можете проверить приведенный выше код я могу добавить метод "move" и любые методы во время выполнения через prototype. Так это прототип на основе классического наследования? Если да, то что такое фактическое классическое наследование и наследование прототипов? Меня это смущает.
прототипным наследованием.
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);
это похоже на классическое наследование? Я совершенно запутался в том, что такое прототип наследство? Что такое классическое наследование? Почему классическое наследование плохо?
можете ли вы дать мне простой пример для лучшего понимания этих простым способом.
спасибо,
Шива
2 ответов:
оба примера кода, которые вы продемонстрировали в своем вопросе, используют прототипное наследование. Фактически любой объектно-ориентированный код, который вы пишете в JavaScript, является парадигмой прототипического наследования. JavaScript просто не имеет классического наследования. Это должно немного прояснить ситуацию:
Inheritance | +-----------------------------+ | | v v Prototypal Classical | +------------------------------+ | | v v Prototypal Pattern Constructor Pattern
краткий обзор объектно-ориентированного программирования
как прототипного наследования и наследование объектно-ориентированной парадигм программирования (т. е. они имеют дело с объектами). Объекты-это просто абстракции, которые инкапсулируют свойства объекта реального мира (т. е. они представляют реальные слова в программе). Это называется абстракция.
абстракция: представление реальных вещей в компьютерных программах.
теперь некоторые объекты имеют много общего. Например, велосипед грязи и Харлей Дэвидсон у них много общего.
грязи велосипед:
Харлей-Дэвидсон:
велосипед грязи и Харлей Дэвидсон оба велосипеды. Следовательно, велосипед-это обобщение как велосипеда грязи, так и Harley Davidson.
Bike | +---------------------------------+ | | v v Mud Bike Harley Davidsonв приведенном выше примере велосипед, Велосипед грязи и Harley Davidson все абстракции. Однако велосипед-это более общая абстракция грязи велосипед и Harley Davidson (т. е. как велосипед грязи, так и Harley Davidson являются конкретными типами велосипедов).
обобщение: абстракция более конкретной абстракции.
в объектно-ориентированном программировании мы создаем объекты (которые являются абстракциями объектов реального мира) и используем классы или прототипы для создания обобщений этих объектов. Обобщения создаются путем наследования. Велосипед-это обобщение велосипеда грязи. Следовательно грязевые велосипеды наследуют от велосипедов.
Классическое Объектно-Ориентированное Программирование
в классическом объектно-ориентированном программировании мы имеем два типа абстракций: классы и объекты. Объект, как упоминалось ранее, является абстракцией сущности реального мира. Класс, с другой стороны, является абстракцией объекта или другого класса (т. е. это обобщение). Например, рассмотрим:
+----------------------+----------------+---------------------------------------+ | 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. | +----------------------+----------------+---------------------------------------+как вы можете видеть в классическом объектно-ориентированном программировании языковые объекты - это только абстракции (т. е. все объекты имеют уровень абстракции 1), а классы-только обобщения (т. е. все классы имеют уровень абстракции больше 1).
объекты в классических объектно-ориентированных языков программирования могут быть созданы только путем создания экземпляра класса:
class Human { // ... } class Man extends Human { // ... } Man johnDoe = new Man();при суммировании в классических объектно-ориентированных языках программирования объекты являются абстракциями объектов реального мира, а классы-обобщениями (т. е. абстракции объектов или других классов).
следовательно, по мере увеличения уровня абстракции сущности становятся более общими, а по мере уменьшения уровня абстракции сущности становятся более конкретными. В этом смысле уровень абстракции аналогичен шкале от более конкретных сущностей до более общих сущностей.
Прототипное Объектно-Ориентированное Программирование
прототипные объектно-ориентированные языки программирования намного проще, чем классические объектно-ориентированные языки программирования, потому что в прототипном объектно-ориентированном программировании мы имеем только один тип абстракции (т. е. объекты). Например, рассмотрим:
+----------------------+----------------+---------------------------------------+ | 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. | +----------------------+----------------+---------------------------------------+объекты в прототипных объектно-ориентированных языках программирования могут быть созданы либо ex-nihilo (т. е. из ничего), либо из другого объекта (который становится прототипом вновь созданного объекта):
var human = {}; var man = Object.create(human); var johnDoe = Object.create(man);по моему скромному мнению, прототипные объектно-ориентированные языки программирования являются более мощными, чем классические объектно-ориентированные языки программирования, потому что:
- существует только один тип абстракция.
- обобщения-это просто объекты.
к настоящему времени вы, должно быть, поняли разницу между классическим наследованием и прототипным наследованием. Классическое наследование ограничено классами, наследующими от других классов. Однако прототипное наследование включает в себя не только прототипы, наследуемые от других прототипов, но и объекты, наследуемые от прототипов.
Изоморфизм Класса Прототипов
вы должны были заметил, что прототипы и классы очень похожи. Это правда. Они. На самом деле они настолько похожи, что вы можете использовать прототипы для моделирования классов:
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; } }используя вышеуказанные
прежде чем перейти к наследству, мы рассмотрим два основной модели для создания экземпляров (объектов) в JavaScript:
классической модели: объект создается из чертежа (класса)
class Person { fn() {...} } // or constructor function say, function Person() {} // create instance let person = new Person();прототипная модель: объект создается непосредственно из другого объекта.
// base object let Person = { fn(){...} } // instance let person = Object.create(Person);в любом случае, наследование* достигается путем связывания объектов с помощью прототипа.
(*методов базового класса доступны через интернет. производный класс через объект прототипа и не требуется явно присутствовать в производном классе.)
вот хорошее объяснение, чтобы лучше понять (http://www.objectplayground.com/)


Comments