Menu
Coddy logo textTech

Ключевое слово super

Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 37 из 110.

Ключевое слово super предоставляет дочернему классу прямой доступ к его родительскому классу. Вы уже видели его в конструкторах с super(name), но оно полезно и в других контекстах.

Когда вам нужно вызвать конструктор родительского класса, super передает аргументы вверх по цепочке наследования:

class Vehicle {
  String brand;
  int year;
  
  Vehicle(this.brand, this.year);
}

class Car extends Vehicle {
  int doors;
  
  Car(String brand, int year, this.doors) : super(brand, year);
}

Ключевое слово super также позволяет вам обращаться к методам и свойствам родительского класса из дочернего класса. Это особенно полезно, когда вы хотите использовать поведение родителя наряду со своим собственным:

class Animal {
  String name;
  
  Animal(this.name);
  
  void makeSound() {
    print('$name makes a sound');
  }
}

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void makeSound() {
    super.makeSound();  // Сначала вызываем метод родителя
    print('$name says meow!');
  }
}

Когда вы вызываете super.makeSound(), вы явно вызываете версию метода родительского класса. Без super, вызов makeSound() будет ссылаться на метод текущего класса, что потенциально может привести к бесконечной рекурсии.

Представьте super как способ сказать «используй версию моего родителя» — будь то конструктор, метод или свойство.

challenge icon

Задание

Легко

Давайте создадим систему обмена сообщениями, которая демонстрирует, как ключевое слово super позволяет дочерним классам получать доступ к поведению родительского класса и расширять его. Вы создадите иерархию, в которой различные типы сообщений строятся на основе базового класса сообщений.

Вы организуете свой код в два файла:

  • message.dart: Определите здесь ваши классы сообщений:
    • Класс Message (родительский) со свойствами String sender и String content. Включите конструктор, который принимает оба значения, и метод display(), который выводит From [sender]: [content]
    • Класс UrgentMessage, который расширяет Message. Он должен иметь дополнительное свойство String priority. Конструктор принимает sender, content и priority, передавая первые два родительскому классу с помощью super. Переопределите метод display(), чтобы он сначала вызывал родительскую версию с помощью super.display(), а затем выводил Priority: [priority] на следующей строке
  • main.dart: Импортируйте файл сообщений и продемонстрируйте, как super работает как в конструкторах, так и в методах:
    • Создайте обычный Message от 'Alice' с содержимым 'Hello there!'
    • Вызовите его метод display()
    • Выведите пустую строку для разделения
    • Создайте UrgentMessage от 'Bob' с содержимым 'Server is down!' и приоритетом 'HIGH'
    • Вызовите его метод display()

Обратите внимание, как UrgentMessage использует super двумя способами: в конструкторе для передачи данных родителю и в переопределенном методе для включения вывода родителя перед добавлением своего собственного.

Ожидаемый результат:

From Alice: Hello there!

From Bob: Server is down!
Priority: HIGH

Шпаргалка

Ключевое слово super предоставляет доступ к родительскому классу из дочернего класса.

Используйте super() в конструкторе дочернего класса для передачи аргументов в конструктор родителя:

class Vehicle {
  String brand;
  int year;
  
  Vehicle(this.brand, this.year);
}

class Car extends Vehicle {
  int doors;
  
  Car(String brand, int year, this.doors) : super(brand, year);
}

Используйте super для вызова родительских методов из переопределенных методов:

class Animal {
  String name;
  
  Animal(this.name);
  
  void makeSound() {
    print('$name makes a sound');
  }
}

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void makeSound() {
    super.makeSound();  // Сначала вызываем метод родителя
    print('$name says meow!');
  }
}

Без super прямой вызов имени метода относится к версии текущего класса, что может привести к бесконечной рекурсии в переопределенных методах.

Попробуйте сами

import 'message.dart';

void main() {
  // TODO: Создайте обычное Message от 'Alice' с содержимым 'Hello there!'
  
  // TODO: Вызовите метод display() для этого сообщения
  
  // TODO: Выведите пустую строку для разделения
  
  // TODO: Создайте UrgentMessage от 'Bob' с содержимым 'Server is down!' и приоритетом 'HIGH'
  
  // TODO: Вызовите метод display() для этого срочного сообщения
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование