Мы запускаем серию постов о принципах объектно-ориентированного программирования (ООП). Вы скажете, что это база, но и ее нужно иногда повторять. Поехали🚀
Dart — язык с ООП-подходом, поэтому без его ключевых принципов сложно представить разработку. Для начала разберемся, что вообще такое ООП.
Что такое ООП?
Объектно-ориентированное программирование (ООП) — это парадигма, основанная на использовании объектов, которые содержат данные (в виде полей) и поведение (в виде методов).
Звучит сложно? Если проще: объект — это экземпляр класса, а класс описывает структуру и поведение этих объектов.
ООП помогает:
✔️ структурировать код
✔️ переиспользовать функциональность
✔️ облегчить масштабирование и поддержку проекта
Основные принципы ООП:
▫️ наследование
▫️ инкапсуляция
▫️ полиморфизм
▫️ абстракция
Сегодня разберем наследование.
Что такое наследование?
Наследование — это механизм, который позволяет одному классу (дочернему) унаследовать свойства и методы другого класса (родительского).
Представьте, что вы пишете посты для Telegram. У вас есть базовый класс Article с методами write(), publish() полями title и author:
class Article {
const Article(this.title, this.author);
final String title;
final String author;
void write() => print('Статья $title ...');
void publish() => print('Публикация статьи ...');
}Вместо дублирования логики — создаем дочерний класс и наследуем поведение:
class TutorialArticle extends Article {
const TutorialArticle(super.title, super.author, this.topic);
/// Дочерние классы могут вызывать конструкторы родительского класса
/// с помощью ключевого слова `super`, передавая необходимые параметры.
/// Это важно для инициализации базового состояния.
final String topic;
void explain() => print('Объяснение темы: $topic');
@override
void publish() {
super.publish(); // сохраняем поведение родителя
print('Дополнительные шаги для публикации туториала по теме: $topic');
}
}Используем:
void main() {
final article = TutorialArticle('ООП в Dart', 'Роза', 'Наследование');
article.write(); // унаследовано
article.publish(); // унаследовано
article.explain(); // новое поведение
}В итоге:
▫️Базовый класс — содержит общую функциональность
▫️Дочерний класс — расширяет или переопределяет поведение
А что насчет наследования в dart?
В dart наследование реализуется через ключевое слово
extends:class Child extends Parent { ... }📝 Прежде чем создавать базовый класс, загляните в пост о модификаторах классов.
Кроме того, Dart использует mixin-based inheritance. Класс может наследовать только один суперкласс (
extends), но может использовать несколько миксинов (with) для добавления поведения.Кстати, в Dart можно не только наследовать реализацию через extends, но и реализовывать интерфейсы с помощью implements. Тогда ты сам переопределяешь все методы, но это уже не наследование поведения.
Композиция vs наследование
Наследование — не единственный способ повторного использования кода. Есть композиция, когда один объект включается в другой, как поле. Такой подход часто делает код более гибким и читаемым. Об этом — в следующих постах.
В двух словах:
▪️
extends — наследуем реализацию (и можем ее переопределить)▪️
implements — реализуем интерфейс (обязаны реализовать все вручную)▪️
with — подключаем миксины (многоразовые наборы методов)▪️ композиция — объединяем объекты, как части (вложенность, а не наследование)
На этом все! В следующем посте — инкапсуляция. Подписывайтесь, чтобы не пропустить💙
