Переопределение toString()
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 70 из 110.
Когда вы выводите объект в Dart, вы можете увидеть что-то вроде Instance of 'Person' — это не очень информативно. Это происходит потому, что каждый класс наследует стандартный метод toString() от Object, который возвращает только имя класса.
Переопределив toString(), вы можете предоставить осмысленное строковое представление ваших объектов:
class Person {
String name;
int age;
Person(this.name, this.age);
@override
String toString() {
return 'Person(name: $name, age: $age)';
}
}
void main() {
var person = Person('Alice', 30);
print(person); // Person(name: Alice, age: 30)
}Без переопределения print(person) выведет Instance of 'Person'. С ним вы получите полезную информацию о состоянии объекта.
Метод toString() вызывается автоматически всякий раз, когда Dart необходимо преобразовать ваш объект в строку — в инструкциях print(), интерполяции строк или при конкатенации с другими строками:
var message = 'User: $person'; // toString() вызывается автоматически
print('Found: ' + person.toString()); // Явный вызовХорошо реализованный toString() значительно упрощает отладку, позволяя быстро проверять значения объектов в процессе разработки.
Задание
ЛегкоДавайте создадим систему каталога товаров, где каждый товар отображает свою информацию в чистом, читаемом формате при выводе на печать. Вы попрактикуетесь в переопределении метода toString(), чтобы сделать ваши объекты более удобными для отладки и использования.
Вы организуете свой код в два файла:
product.dart: Создайте классProduct, который представляет товар в магазине. Ваш товар должен иметьname(String),price(double) иquantity(int). Переопределите методtoString(), чтобы он возвращал отформатированную строку именно в таком формате:Product(name: [name], price: $[price], qty: [quantity])main.dart: Импортируйте файл с товаром и продемонстрируйте, как переопределениеtoString()делает печать объектов гораздо более полезной. Создайте три товара и распечатайте их, чтобы увидеть ваше пользовательское строковое представление в действии:- Товар с именем
'Laptop', ценой999.99и количеством5 - Товар с именем
'Mouse', ценой29.5и количеством50 - Товар с именем
'Keyboard', ценой75.0и количеством30
Featured: [product], используя товар Laptop.- Товар с именем
Обратите внимание, как печать каждого товара напрямую показывает значимую информацию вместо малополезного сообщения Instance of 'Product'. Ваш метод toString() вызывается автоматически как в операторах print(), так и при использовании интерполяции строк.
Ожидаемый вывод:
Product(name: Laptop, price: $999.99, qty: 5)
Product(name: Mouse, price: $29.5, qty: 50)
Product(name: Keyboard, price: $75.0, qty: 30)
Featured: Product(name: Laptop, price: $999.99, qty: 5)Попробуйте сами
import 'product.dart';
void main() {
// TODO: Создайте три экземпляра Product:
// 1. Laptop - price: 999.99, quantity: 5
// 2. Mouse - price: 29.5, quantity: 50
// 3. Keyboard - price: 75.0, quantity: 30
// TODO: Выведите каждый продукт (toString() будет вызван автоматически)
// TODO: Выведите сообщение о рекомендуемом товаре, используя интерполяцию строк
// Формат: Featured: [laptop product]
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий