Конструкторы и наследование
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy. Урок 41 из 110.
Когда дочерний класс расширяет родительский, конструктор родителя должен быть вызван для правильной инициализации унаследованных полей. Dart предоставляет гибкие способы обработки этого через список инициализации с использованием super.
Если у родителя есть параметризованный конструктор, дочерний класс должен вызывать его явно:
class Person {
String name;
int age;
Person(this.name, this.age);
}
class Student extends Person {
String school;
Student(String name, int age, this.school) : super(name, age);
}В Dart 2.17 появились супер-параметры — более лаконичный синтаксис, который передает параметры напрямую в конструктор родительского класса:
class Student extends Person {
String school;
// super.name и super.age передаются напрямую в конструктор Person
Student(super.name, super.age, this.school);
}При работе с именованными конструкторами вы указываете, какой родительский конструктор следует вызвать:
class Employee extends Person {
String department;
Employee(super.name, super.age, this.department);
Employee.intern(String name, this.department) : super(name, 18);
}Основное правило простое: родительский класс должен быть полностью инициализирован до того, как дочерний класс добавит свои собственные свойства. Независимо от того, используете ли вы традиционный вызов super() или более новые супер-параметры, Dart гарантирует, что цепочка наследования правильно выстроена от родителя к потомку.
Задание
ЛегкоДавайте создадим систему инвентаризации товаров, которая демонстрирует, как конструкторы работают с наследованием. Вы создадите иерархию, в которой различные типы товаров расширяют базовый класс продукта, и каждый из них требует правильной инициализации через родительские конструкторы.
Вы организуете свой код в двух файлах:
product.dart: Определите здесь иерархию ваших продуктов:- Класс
Productсо свойствамиString nameиdouble price, конструктором, принимающим оба значения, и методомinfo(), который выводит[name]: $[price] - Класс
Book, который расширяетProductи добавляет свойствоString author. Используйте супер-параметры для передачиnameиpriceв родительский конструктор - Класс
Electronics, который расширяетProductи добавляет свойствоint warranty(в месяцах). Используйте традиционный вызовsuper()в списке инициализации для передачи значений родителю
- Класс
main.dart: Импортируйте файл с продуктами и продемонстрируйте оба подхода к наследованию конструкторов:- Создайте
Bookс именем'Dart Essentials', ценой29.99и автором'Jane Smith' - Вызовите его метод
info(), затем выведитеAuthor: [author] - Выведите пустую строку
- Создайте
Electronicsс именем'Wireless Mouse', ценой45.50и гарантией24 - Вызовите его метод
info(), затем выведитеWarranty: [warranty] months
- Создайте
Оба дочерних класса наследуют метод info() от Product без необходимости его переопределения. Ключевое различие заключается в том, как они вызывают родительский конструктор: Book использует более чистый синтаксис супер-параметров, в то время как Electronics использует традиционный подход с super() в списке инициализации.
Ожидаемый результат:
Dart Essentials: $29.99
Author: Jane Smith
Wireless Mouse: $45.5
Warranty: 24 monthsПопробуйте сами
import 'product.dart';
void main() {
// TODO: Создайте Book с:
// - name: 'Dart Essentials'
// - price: 29.99
// - author: 'Jane Smith'
// TODO: Вызовите метод info() книги
// TODO: Выведите "Author: [author]"
// TODO: Выведите пустую строку
// TODO: Создайте Electronics с:
// - name: 'Wireless Mouse'
// - price: 45.50
// - warranty: 24
// TODO: Вызовите метод info() электроники
// TODO: Выведите "Warranty: [warranty] months"
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыБиблиотеки и импортВведение в ООПКлассы и объектыКлючевое слово thisМетодыПеременные экземпляраОсновы конструкторовИтоги — Простой калькулятор4Null-безопасность
Введение в Null-безопасностьNullable и Non-Nullable типыОператоры ? и !Ключевое слово Late и Null-безопасностьNull-aware операторыNull-безопасность в классахИтоги — Система профилей пользователей7Абстрактные классы и интерфейсы
Абстрактные классыАбстрактные методыИнтерфейсы в DartНеявные интерфейсыРеализация против наследованияМножественные интерфейсыИтоги — Калькулятор фигур10Коллекции и обобщения
Обзор List, Set, MapТипобезопасные коллекцииОбобщенные классыОбобщенные методыОграничения обобщенийIterable и IteratorИтоги: Обобщенное хранилище13Продвинутые концепции ООП
Композиция против наследованияМетоды расширенияВызываемые классыЗапечатанные классы (Dart 3)Записи (Dart 3)Паттерны и сопоставление (3.0)Перечисления с методами16Проект: Управление библиотекой
Обзор проектаКлассы Book и User2Конструкторы в Dart
Конструктор по умолчаниюИменованные конструкторыСписки инициализацииКонстантные конструкторыФабричные конструкторыПеренаправляющие конструкторыИтоги — Shape Builder5Инкапсуляция
Публичные и приватные членыСоглашение о префиксе _Приватность на уровне библиотекГеттеры и сеттеры: подробный разборСкрытие данныхИтоги — Записи о студентах8Mixins
Введение в MixinsСоздание MixinsИспользование нескольких MixinsКлючевое слово on в MixinsMixin и наследованиеMixin и интерфейсИтоги: Система животных11Специальные методы
Переопределение toString()Переопределение hashCode и ==Интерфейс ComparableМетод call()Переопределение noSuchMethodПовторение — Пользовательская коллекция14Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy3Свойства классов
Члены экземпляра и статические членыПоля Final и ConstПеременные LateСтатические методы и поляГеттеры и сеттерыИтоги — Менеджер банковского счета6Наследование
Основы наследованияКлючевое слово superПереопределение методовАннотация @overrideКлючевое слово final для классовКонструкторы и наследованиеИтоги: Иерархия сотрудников9Полиморфизм
Основы полиморфизмаПолиморфизм через интерфейсыПроверка типов во время выполненияОператоры is и asКлючевое слово covariantИтоги — Обработчик платежей12Асинхронное ООП
Futures и async/awaitОсновы StreamsКонтроллеры StreamАсинхронные конструкторыАсинхронность в методах классовИтоги — Data Fetcher15Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн РепозиторийПотренируйтесь самостоятельно: Онлайн-компилятор Dart