ООП
Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на представлении программы как набора взаимодействующих объектов.
Объект — это структура данных (набор взаимосвязанных полей), которая может быть дополненна каким-то поведением (связанными функциями — методами).
Класс — это шаблон, определяющий структуру данных (поля) и поведение (методы) для множества однотипных объектов.
Основные принципы ООП
Инкапсуляция
Это размещение в одном компоненте данных и методов, которые с ними работают, и реализация механизма управления данными, в частности сокрытие внутренней реализации объекта.
Инкапсуляция нужна для защиты внутреннего состояния объекта от неконтролируемого изменения и уменьшения связности между компонентами программы.
Наследование
Это возможность создания нового класса на основе существующего, когда дочерний класс автоматически перенимает (наследует) поля и методы родительского класса.
Наследование позволяет переиспользовать код и строить на основе этого иерархии классов.
Полиморфизм
Это способность объектов с одинаковым интерфейсом выполнять разные действия в зависимости от их конкретного типа.
Наследование позволяет достигать гибкости и расширяемости кода.
Абстракция
Это моделирование только тех характеристик объекта, которые существенны для текущей задачи, и игнорирование несущественных деталей.
В коде
Инкапсуляция обычно реализована через модификаторы доступа. Это атрибуты, определяющие условие доступа, которые могут быть применены к полям и методам.
Основные модификаторы доступа:
public
: поле доступно вездеprivate
: поле доступно только внутри своего классаprotected
: поле доступно внутри своего класса и в наследуемых классах
class Database {
public dialect: string;
private connectionString: string;
}
Полиморфизм обычно реализуется через механизм переопределения функций и методов (overriding) и работу со ссылками базового типа.
Также в языке могут быть интерфейсы — это абстрактные типы, которые определяют требования к объекту, но не содержат никакой реализации.
interface Playable {
play(): void;
}
class VideoPlayer implements Playable {
public play(): void { /* video */ }
}
class AudioPlayer implements Playable {
public play(): void { /* audio */ }
}
Особые методы:
- конструктор: выполняется при создании объекта
- деструктор: выполняется при удалении объекта из памяти
- геттер (getter): выполняется при обращении к полю
- сеттер (setter): выполняется при изменении поля
- абстрактный: метод без реализации (только название и аргументы)
- статический: без доступа к состоянию объекта, связан напрямую с классом
Абстрактный класс — это класс, в котором присутствуют абстрактные методы. При наследовании от абстрактного, дочерний класс должен реализовать абстракции.
Статические методы обычно используются для удобной композиции функций, причастных к данному классу.
class XElement {
public static parse(input: string): XElement {}
public static tryParse(input: string): XElement | null {}
}
Агрегация и композиция
Кроме наследования, связь между классами может проявляться в виде ассоциации, когда один класс включает в себя другой в качестве одного из полей. Это отношение вида "часть-целое".
Агрегация — это отношение, при котором объект содержит внутри себя другие объекты, но они могут существовать независимо.
- части могут принадлежать нескольким объектам одновременно
- части создаются и уничтожаются независимо
- обычно реализуется через передачу объектов извне
class Driver {
constructor(public readonly name: string) {}
}
class Car {
constructor(private readonly driver: Driver) {}
}
const driver = new Driver('John');
const car1 = new Car(driver);
const car2 = new Car(driver);
Композиция — это отношение, где части не могут существовать независимо от целого, т.е. внутренний класс не существует отдельно от основного.
- владение: внутренние объекты принадлежат основному
- жизненный цикл частей управляется целым
- внутренние объекты создаются внутри конструктора основного класса
class Car {
private readonly engine: Engine;
constructor() { this.engine = new Engine(); }
}
const car = new Car();