Сейчас меня интересуют лишь их названия, дальше мы более подробно поговорим о каждом из них.
ООП строится на трех базовых принципах:
Но классически иногда выделяют принцип Абстракции.
Я бы хотел услышать именно ваше мнение, которое сформировалось у вас в ходе получения опыта разработки. Здесь нет правильного и неправильного ответа.
Инкапсуляция — это принцип ООП, который подразумевает, что некоторый объектный тип данных (реализованный с помощью класса, структуры или перечисления) объединяет в себе данные и методы для работы с этими данными, при этом скрывая реализацию от пользователя. При этом каждый из элементов типа может иметь различную область видимости.
Некоторые определяют инкапсуляцию исключительно, как распределение
public
иprivate
внутри типа. Я считаю такой подход неверным, модификаторы контроля доступа — это следствие инкапсуляции, а не инкапсуляция. И данная возможность идет бок-о-бок с принципом «Абстракция»
Абстракция — это выделение у объекта значимых характеристик и функций, которыми может оперировать пользователь при работе с объектом, и отбрасывание незначимых.
Наследование предусматривает возможность создания новых объектных типов на основе уже существующих, с сохранением и/или переопределением его функциональности.
Наследование в классическом виде доступно только при использовании классов. Но в контексте протокол-ориентированного программирования, оно становится доступным для протоколов и структур.
Примеры:
// ПРИМЕР 1 // Наследование класса // Базовый класс class Animal { var name: String init(name: String) { self.name = name } func say() -> String? { return nil } } // Дочерний класс class Dog: Animal { override func say() -> String? { return "woff" } } // ПРИМЕР 2 // Наследование структурой протокола // Протокол protocol Moveable { var step: Int { get set } } // Расширение протокола, добавляющее дефолтную функциональность extension Moveable { mutating func move() { step += 1 } } // Класс, наследующий протокол struct Programmer: Moveable { var step: Int = 0 } var programmer = Programmer() programmer.move() programmer.step // 1
С наследованием не все так просто, как может показаться на первый взгляд. Использовать наследование необходимо максимально осторожно (особенно при наличии протоколов в Swift), так как оно приводит к нарушению ортогональности вашего кода. Другими словами наследование хоть и приводит к тому, что у вас появляется возможность полиморфного использования классов, но вы увеличиваете сцепление классов.
Подробнее об этом можно прочитать в этой статье.
Ортогональность — это характеристика системы, которая говорит о том, что элементы системы удовлетворяют двум требованиям:
Самая главная заслуга ортогональности — простое и легкое внесение изменений в код. Модифицируя один компонент ортогональной системы другие даже не заметят этого!
Обе характеристики определяют то, насколько правильно разработчик разделил проект на отдельные компоненты, решают ли компоненты одну и только одну конкретную задачу.
В идеале мы всегда должны стремиться к loose coupling и high cohesion.