Классическое Vs прототипное наследование

После прочтения обоим, у меня просто есть любопытство, как сообщество программирования использует это? В какой ситуации, которая?

Ответы

Ответ 1

Наследование на основе прототипа более гибкое. Любой существующий объект может стать классом, из которого будут создаваться дополнительные объекты. Это удобно, когда ваши объекты предлагают несколько наборов услуг и/или они претерпевают много изменений состояния до того, как ваша программа поступит в тот момент, когда требуется наследование.

Обсуждение подходов моделирования к широкому спектру доступно здесь: http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html

Ответ 2

Существует множество проблем с классическим наследованием, которые не существуют с прототипным наследованием, например:

Классическое наследование

Плотная муфта. Наследование - это самое узкое соединение, доступное в дизайне OO. Уровни потомков имеют глубокое знание своих классов предков.

Негибкие иерархии (ака дупликация по необходимости). Иерархии с одним родителем редко могут описывать все возможные варианты использования. В конце концов, все иерархии являются "неправильными" для новых применений - проблема, которая требует дублирования кода.

Множественное наследование сложно. Часто желательно наследовать от нескольких родителей. Этот процесс чрезмерно сложный, и его реализация несовместима с процессом одиночного наследования, что затрудняет его чтение и понимание.

Хрупкая архитектура. Из-за жесткой связи часто бывает сложно реорганизовать класс с "неправильным" дизайном, поскольку многие существующие функции зависят от существующего дизайна.

Задача Гориллы/Бананы. Часто есть части родителя, которые вы не хотите наследовать. Подкласс позволяет переопределить свойства родителя, но не позволяет вам выбирать, какие свойства вы хотите наследовать.

Прототипное наследование

Чтобы понять, как прототипное наследование решает эти проблемы, вы должны сначала понять, что существуют два разных типа прототипного наследования. JavaScript поддерживает оба:

Делегирование. Если свойство не найдено в экземпляре, оно выполняется в экземпляре экземпляра экземпляра. Это позволяет вам распространять методы среди многих случаев, предоставляя вам бесплатный шаблон для мух.

конкатенация. Возможность динамически добавлять свойства к объекту позволяет вам свободно копировать любые свойства из одного объекта в другой, все вместе или выборочно.

Вы можете комбинировать обе формы прототипного наследования для достижения очень гибкой системы повторного использования кода. На самом деле это настолько гибко, что тривиально реализовать классическое наследование с прототипами. Обратное неверно.

Прототипное наследование позволяет использовать большинство важных функций, которые вы найдете на классических языках. В JavaScript функции закрытия и factory позволяют реализовать частное состояние, а функциональное наследование можно легко комбинировать с прототипами, чтобы добавить микшины, которые поддерживают конфиденциальность данных.

Некоторые преимущества прототипного наследования:

Свободная связь. Экземпляру никогда не требуется прямая ссылка на родительский класс или прототип. Возможно сохранить ссылку на прототип объекта, но он не рекомендуется, потому что это будет способствовать жесткой связи в иерархии объектов - одной из самых больших ошибок классического наследования.

Плоские иерархии. Это тривиально с прототипом OO, чтобы сохранить иерархии наследования плоскими - используя конкатенацию и делегирование, вы можете иметь один уровень делегирования объектов и один экземпляр без ссылок на родительские классы.

Тривиальное множественное наследование. Наследование от нескольких предков так же просто, как объединение свойств нескольких прототипов с использованием конкатенации для создания нового объекта или нового делегата для нового объекта.

Гибкая архитектура. Поскольку вы можете наследовать выборочно с прототипом OO, вам не нужно беспокоиться о проблеме "неправильного дизайна". Новый класс может наследовать любую комбинацию свойств из любой комбинации исходных объектов. Из-за простоты выравнивания иерархии изменение в одном месте не обязательно вызывает рябь по длинной цепочке потомков.

Больше не горилл. Селективное наследование устраняет проблему банана горилл.

Я не знаю, какое преимущество имеет классическое наследование над прототипным наследованием. Если кто-нибудь знает о любом, пожалуйста, просветите меня.

Ответ 3

Так как Javascript не поддерживает "классическое" наследование, как большинство понимает (и вы не указали никаких ссылок на то, что вы читали), я предполагаю, что вы имеете в виду наследование, обрабатываемое следующим образом: -

 function base() {
    var myVar;
    this.someBaseFunc = function() { }
 }


 function derived() {
    base.call(this);
    var someOtherVar;
    this.SomeOtherFunc = function() { }
 }

Мое общее правило:

  • Если классы сложны, а экземпляры мало используют "классический" подход. Это позволяет классам публично публиковать только те функции, которые должны быть преданы гласности.
  • Если класс прост и много экземпляров используют прототипный подход. Это ограничивает накладные расходы на определение и хранение ссылок на функции снова и снова по мере создания экземпляров.