Вы, наверное, знаете, как работает ООП. Класс Dog
наследуется от класса Animal
, что означает, что если у вас есть Dog
, вы получаете доступ к методам из Animal
. На самом деле это всего лишь подмножество ООП. Вы можете быть объектно-ориентированным без классов, и это то, что делает JavaScript.
Класс - это план. Он содержит информацию о том, что есть у каждого экземпляра этого класса . Он сообщает вам, какие методы и свойства существуют и как вы можете использовать этот класс вещей.
Сам класс фактически не содержит никаких данных. Это работа объекта. Класс - это проект дома, а объект - это настоящий дом с деревом, плиткой, кирпичом и всем весом настоящего дома. Экземпляр содержит фактические данные, индивидуальные только для этого экземпляра. Возможно, вы использовали тот же план для своего дома, что и ваш сосед, но это не значит, что вы можете спать в их постели.
Разница между экземплярами и классами фундаментальна для понимания ООП большинством людей. Но это не обязательно для ООП. Есть способ использовать ООП без классов. В конце концов, это объектно-ориентированное программирование: в центре внимания шоу - объекты, а не классы.
Стиль ООП, в котором нет разницы между классами и объектами, называется программированием на основе прототипов (чтобы облегчить нашу жизнь, мы будем называть его PBP).
В PBP каждый объект может быть индивидуальным. Он содержит оба своих метода и одновременно данные. Обычно вы можете добавлять новые свойства и методы к объекту, когда захотите, даже во время работы программы.
Если это звучит так, как будто только несколько программистов используют для решения своих краевых задач, вы будете удивлены. Одним из самых популярных языков в мире является язык PBP: JavaScript.
В JavaScript нет классов в ООП-смысле слова, основанном на классах. JavaScript работает с объектами. Если вы хотите инкапсулировать вместе несколько функций и свойств, вы должны создать объект, содержащий функции и свойства, а не класс.
const animal = {
numberOfLegs: 4,
sleep: () => print("Zzz")
}
Это объект, у которого есть свойство и функция, которая выполняет некоторую работу. Это отличается от класса, потому что функция сама является частью данных, которые есть у объекта. Оно так же изменчиво, как состояние свойства.
animal.sleep = null
Теперь, внезапно, у животного больше нет функции. У JavaScript нет чертежей, у него есть только дома.
А как насчет наследования?
Основным свойством класса является то, что он может наследовать методы и свойства от других классов. И House
, и Apartment
могут наследовать от Residence
, чтобы не дублировать один и тот же код в обоих классах.
Но опять же, классы не нужны для наследования. В PBP наследование полностью осуществляется с помощью объектов.
Ранее я упоминал, что в PBP объект содержит все свои методы и свойства, а также их фактическое состояние. Таким образом, единственный способ унаследовать все это - скопировать (или сделать ссылку) на все эти методы и свойства. Именно это и делают языки PBP, и это называется прототипное наследование.
Если мы хотим создать объект dog
, который будет иметь доступ к тем же методам, что и animal
, мы можем просто сделать dog
содержать animal
, поскольку методы находятся внутри animal
.
const dog = {
prototype: animal,
bark: () => print("Woof!")
}
Если мы хотим заставить dog
есть пищу, мы можем сделать следующее:
dog.prototype.eatFood(10)
К счастью, JavaScript автоматически вызывает функции прототипа. Если функция не существует для этого объекта, он будет искать функцию в прототипе. Прототип может сам содержать другой прототип, поэтому JS будет выполнять поиск до тех пор, пока не найдет искомую функцию.
Причина, по которой они называются языками на основе прототипов, заключается в том, что прототип, в отличие от класса, является конкретным. Прототип - это рабочая вещь, а не чертеж. Возможно, вы не захотите продавать прототип миллионам клиентов, но это действительно работает. Затем вы используете этот прототип для создания кучи копий, которые вы действительно будете использовать. Прямо как на фабрике.
Объект animal
- прототип животного. Это такой же объект, как и любой другой, но он будет использоваться для создания новых, конкретных животных, таких как dog
.
Это лучше, чем классы?
PBP более прост, чем ООП на основе классов. Он имеет меньше движущихся частей и полностью прозрачен. Вы можете увидеть, как это работает. ООП на основе классов - это дополнительный слой абстракции. Это означает, что у PBP есть много преимуществ, но есть и недостатки.
Главное преимущество PBP заключается в его гибкости. Чертежи - это то, что нужно делать заранее, и они должны быть правильными. Если вы строите дом, у вас будет много проблем, если вы поймете, что на полпути к постройке крыши вы забыли добавить окно в чертеж. Классы похожи: вы создаете их до создания и использования объектов. Вы должны знать, какие методы и свойства вам понадобятся, прежде чем начать его использовать. Независимо от того, насколько вы хороши в программировании, вы не сможете все предсказать.
Если вам не нужно создавать класс заранее, вы можете сразу приступить к созданию своих объектов. Вы можете адаптировать их по мере использования без больших затрат. Это очень полезно в программировании, где требования все время меняются. Вам нужна возможность быстро и легко меняться.
Но быстрое и легкое изменение сопряжено с большим риском: правильностью. Существуют чертежи, позволяющие спланировать дом еще до его постройки, поэтому ошибки обнаруживаются на ранней стадии, и рабочие не теряются во время строительства. Если вы попытаетесь построить дом, просто сделав это и посмотрев, куда он вас приведет, вы, вероятно, закончите тем, что дом рухнет на вас. То же самое и с программированием: вам нужно убедиться, что ваша кодовая база правильная и правильная. Если каждый сможет просто пойти и начать все менять, она быстро рухнет на себя.
Как и все в программировании, PBP и ООП на основе классов попадают в спектр компромиссов. С одной стороны, PBP гибок, с ним легко работать, что ускоряет разработку. С другой стороны, ООП на основе классов является более жестким и надежным, что приводит к меньшему количеству ошибок. Для решения различных задач требуются разные инструменты, и, зная PBP, вы лучше подготовлены для решения проблем, для которых это необходимо. Удачного кодирования!
Примечание. Это репост с сайта programmingwords.com. Это блог, в котором каждый месяц публикуются два новых термина из области компьютерных наук. Проверьте это, если вас интересуют compsci, компиляторы или языки программирования! :)
Использованная литература:
Программирование на основе прототипов
https://en.wikipedia.org/wiki/Prototype-based_programming
Наследование и цепочка прототипов - JavaScript
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain