Мы тут постепенно раскладываем по полочкам объектно-ориентированное программирование. В первой части мы говорили про спагетти-код и предназначение ООП. Дальше разбирали классы — то, из чего делаются объекты. Теперь, наконец-то, сами объекты.
На примере Айфона
Вот лаборатория, конструкторское бюро. Там у нас сидят дизайнеры, инженеры и программисты. Они сделали чертежи и инструкции, как собирать новые Айфоны. Если все эти инструкции собрать, их совокупность можно назвать классом. Это такая «идея Айфона».
Из предыдущей статьи мы знаем, что в классе мы можем прописать свойства и методы.
Свойства — это, грубо говоря, данные. У Айфона может быть «свойство» в виде записанной на него операционной системы.
Методы — это, грубо говоря, «что это устройство может делать». У Айфона могут быть «методы» типа позвонить, отправить смс, запустить камеру, сделать снимок.
Всё это множество свойств и методов составляет общий класс, который мы потом используем для создания нашего воображаемого Айфона.
Когда прописан класс, завод может взять его (то есть все эти чертежи и спецификации) и сделать много копий айфонов. Каждый телефон, который выходит с завода, имеет чётко прописанные характеристики: размер памяти, диагональ экрана, цвет корпуса и так далее. Это всё было заранее продумано и записано в инструкциях по изготовлению. При этом все телефоны получаются одновременно одинаковые и разные.
Одинаковые: все телефоны одной модели не отличаются почти ничем. У них одинаковое железо, характеристики и возможности. Если взять с конвейера два случайных телефона, между ними не будет никакой разницы. Все они работают одинаково — так, как задумали проектировщики.
Разные: при этом у каждого айфона есть уникальный серийный номер и другие уникальные идентификаторы. Какие-то модели могут отличаться цветом корпуса или иметь слот на 2 сим-карты, как версии для китайского рынка.
После того как айфоны выходят с завода и попадают в руки людям, каждый телефон начинает наполняться разными данными: фото, видео, музыка, книги и программы. При обычном использовании в мире нет двух телефонов с полностью одинаковыми данными внутри. Но при этом у всех одинаково запускается камера, одинаковым способом меняются обои и отправляются смс. Это означает, что все свойства и методы работы с данной моделью одинаковы для всех телефонов этой модели. Достаточно понять, как работать с одним, — и вы понимаете, как работать со всеми точно такими же.
Вся эта аналогия с Айфонами нужна, чтобы понять смысл объектов:
- Есть класс — чертёж будущего объекта.
- На основе этого класса можно сделать объект.
- Созданный объект имеет всё, что в него вложено из класса.
- После создания с объектом можно делать всё, что в нём было заложено классом.
- Ещё с объектом можно делать всё остальное, что позволяет язык программирования.
Как создаются объекты
В общем виде на JavaScript объект задаётся вот такой конструкцией. Пока что она абстрактная, просто пример:
class MyClass
prop1 = value1; // свойства класса
prop2 = value2;
constructor(...) { // команда-конструктор, с её помощью создаются новые объекты
// содержимое конструктора
}
method1(...) {} // методы класса, то, что класс умеет делать, и как с ним работать
method2(...) {}
// ...
}
Теперь сделаем конкретный класс, который отвечает за телефон:
class iPhone{
constructor(memory,color) { // при создании будем указывать
размер встроенной памяти и цвет
this.memory = memory; // создаём телефон с заданной памятью…
this.color = color; // … и с заданным цветом
whois() { // метод, который выводит информацию о телефоне
console.log('Память: ' + this.memory + 'Гб. Цвет: ' + this.color);
}
}
}
У нас появилась команда this, которая отвечает за свойства конкретного класса. С её помощью класс обращается внутри себя к нужным значениям. Ещё мы сделали метод whois, который выводит значение памяти и цвет. Каждый объект, который мы создадим на основе этого класса, будет уметь это делать — для этого достаточно написать имя объекта, поставить точку, а потом написать имя метода.
Нам осталось только создать новый объект и проверить, что за данные у него получились внутри и как работает метод:
iPhone_object = new iPhone(64,'Black'); // создаём новый объект
— айфон с определённой памятью и цветом
iPhone_object.whois(); // проверяем, как работает
метод класса в готовом объекте
В других языках принцип создания объектов практически такой же: делаем класс, в нём описываем всё, что нужно, а потом создаём объект на основе этого класса.
Где это использовать
Представьте, что вы делаете игру вроде Арканоида. Вам нужно, чтобы у вас был мячик, платформа и какие-то стены, от которых этот мячик отскакивает.
Можно прописать все взаимодействия через функции и каждую 1/25 секунды анализировать все координаты и отрисовывать все состояния всех предметов в игре. У вас будет огромный зоопарк из проверок, условий и циклов, цель которых будет просто проверять координаты всего.
А можно прописать три класса: мячик, стена и платформа. В класс «мячик» засунуть методы типа «лететь» и «отскочить». В класс «платформа» засунуть методы «двигаться» и, например, свойство «длина». А в класс «стена» засунуть только свойство «положение». И на основе этих трёх классов сделать нужное количество объектов: четыре стены, один мячик, одну платформу.
Дальше вы даёте команду «мячик.лететь(в случайном направлении)» — и волшебным образом у вас получится игра. Объекты будут жить каждый своей жизнью по тем законам, которые вы им прописали. И если вам нужно будет создать второй мячик, вы просто говорите: «Запустить конструктор мячика».
Покажем это на примере в одной из следующих статей.