Сейчас меня интересуют лишь их названия, дальше мы более подробно поговорим о каждом из них.
ООП строится на трех базовых принципах:
Но классически иногда выделяют принцип Абстракции.
Я бы хотел услышать именно ваше мнение, которое сформировалось у вас в ходе получения опыта разработки. Здесь нет правильного и неправильного ответа.
Инкапсуляция — это принцип ООП, который подразумевает, что некоторый объектный тип данных (реализованный с помощью класса, структуры или перечисления) объединяет в себе данные и методы для работы с этими данными, при этом скрывая реализацию от пользователя. При этом каждый из элементов типа может иметь различную область видимости.
Некоторые определяют инкапсуляцию исключительно, как распределение
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.