Method (Метод)

Метод — это функция, которая определяет поведение объекта. Методы делятся на четыре группы: экземплярные методы, перегрузка операторов, геттеры/сеттеры и абстрактные методы.

1. Instance methods Экземплярные методы

  1. Относятся к экземплярам класса;
  2. Имеют прямой доступ к переменным экземпляра, поддерживают ключевое слово this;
  3. Содержат полное тело функции, предназначены для вычислений и логической обработки бизнес-задач.
import 'dart:math';

class Point {
  final double x;
  final double y;

  // Конструктор инициализирует переменные экземпляра
  Point(this.x, this.y);

  // Экземплярный метод: расчет расстояния между двумя точками
  double distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

void main() {
  Point p1 = Point(0, 0);
  Point p2 = Point(3, 4);
  print(p1.distanceTo(p2)); // Вывод 5.0
}Code language: JavaScript (javascript)

2. Operators Перегрузка операторов

  1. Большинство операторов по сути являются экземплярными методами со специальными именами;
  2. Синтаксис объявления: operator Оператор(параметр) ТипВозврата { ... };
  3. Список перегружаемых операторов:
    < > <= >= == ~
    - + / ~/ * %
    | ˆ & << >>> >>
    []= []
  4. Встроенные операторы перегружать нельзя (например !=, реализован Dart автоматически в нижнем слое, ручное определение не требуется);
  5. При перегрузке == обязательно нужно переопределить hashCode, иначе сравнение на равенство будет работать некорректно.
class Vector {
  final int x, y;

  Vector(this.x, this.y);

  // Перегрузка + для сложения векторов
  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  // Перегрузка - для вычитания векторов
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // Перегрузка == для проверки равенства
  @override
  bool operator ==(Object other) =>
      other is Vector && x == other.x && y == other.y;

  // Соответствующее переопределение hashCode
  @override
  int get hashCode => Object.hash(x, y);
}

void main() {
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  assert(v + w == Vector(4, 5));
  assert(v - w == Vector(0, 1));
  print(v + w);
}Code language: JavaScript (javascript)

После перегрузки операторов мы можем выполнять над двумя объектами Vector операции +, -, == и другие, как над обычными числами.

3. Getters and setters Геттеры и сеттеры

  1. get: метод только для чтения, возвращает вычисляемое свойство, не имеет параметров;
  2. set: метод для записи, изменяет связанную переменную, имеет ровно один параметр;
  3. Все переменные экземпляра имеют неявный геттер, изменяемые переменные дополнительно имеют неявный сеттер;
  4. Преимущество: позже обычную переменную можно заменить логикой вычислений без изменения внешнего вызывающего кода;
  5. Операторы инкремента/декремента ++/-- вызывают геттер только один раз и кэшируют значение, чтобы избежать побочных эффектов.
/// Прямоугольник экранной системы координат, начало координат (0,0) в левом верхнем углу
class Rectangle {
  double left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // Геттер: расчет правой границы
  double get right => left + width;

  // Сеттер: задать правую границу и пересчитать left в обратную сторону
  set right(double value) => left = value - width;

  // Геттер: расчет нижней границы
  double get bottom => top + height;

  // Сеттер: задать нижнюю границу и пересчитать top в обратную сторону
  set bottom(double value) => top = value - height;
}

void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);

  // Вызов сеттера
  rect.right = 12;
  assert(rect.left == -8);
  print(rect.left); // -8
}Code language: JavaScript (javascript)

4. Abstract methods Абстрактные методы

  1. Определяют только интерфейс, не имеют тела функции, вместо реализации используется точка с запятой ;;
  2. Могут располагаться только в abstract class абстрактных классах или миксинах (mixin);
  3. Подклассы должны переопределить и реализовать все абстрактные методы, иначе подкласс тоже нужно пометить как abstract.
// Абстрактный класс с абстрактным методом
abstract class Doer {
  // Абстрактный метод: только объявление, без реализации
  void doSomething();
}

// Обычный подкласс, обязан реализовать все абстрактные методы родителя
class EffectiveDoer extends Doer {
  @override
  void doSomething() {
    print("Выполнить конкретную бизнес-логику");
  }
}

void main() {
  Doer worker = EffectiveDoer();
  worker.doSomething(); // Вывод: Выполнить конкретную бизнес-логику
}Code language: JavaScript (javascript)

Сравнение

Тип методаОсновные признакиСинтаксический маркерСценарии применения
Экземплярный метод InstanceДоступ к переменным экземпляра, полное логическое телоСтандартное объявление функцииСтандартное поведение объектов (вычисления, бизнес-операции)
Перегрузка оператора OperatorЭкземплярный метод с специальным именем, ключевое слово operatoroperator +() и другиеПользовательские сложение, вычитание, индексация и сравнение объектов на равенство
Getter/SetterЧтение/запись свойств; get без параметров, set с одним параметромget / setИнкапсуляция вычисляемых свойств, единая точка чтения и записи извне
Абстрактный метод AbstractБез тела метода, только объявление интерфейсаТочка с запятой ; после сигнатурыЗадание спецификации в абстрактном родительском классе, принудительная реализация в подклассах

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *