Метод — это функция, которая определяет поведение объекта. Методы делятся на четыре группы: экземплярные методы, перегрузка операторов, геттеры/сеттеры и абстрактные методы.
1. Instance methods Экземплярные методы
- Относятся к экземплярам класса;
- Имеют прямой доступ к переменным экземпляра, поддерживают ключевое слово
this; - Содержат полное тело функции, предназначены для вычислений и логической обработки бизнес-задач.
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 Перегрузка операторов
- Большинство операторов по сути являются экземплярными методами со специальными именами;
- Синтаксис объявления:
operator Оператор(параметр) ТипВозврата { ... }; - Список перегружаемых операторов:
< > <= >= == ~- + / ~/ * %| ˆ & << >>> >>[]= [] - Встроенные операторы перегружать нельзя (например
!=, реализован Dart автоматически в нижнем слое, ручное определение не требуется); - При перегрузке
==обязательно нужно переопределить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 Геттеры и сеттеры
get: метод только для чтения, возвращает вычисляемое свойство, не имеет параметров;set: метод для записи, изменяет связанную переменную, имеет ровно один параметр;- Все переменные экземпляра имеют неявный геттер, изменяемые переменные дополнительно имеют неявный сеттер;
- Преимущество: позже обычную переменную можно заменить логикой вычислений без изменения внешнего вызывающего кода;
- Операторы инкремента/декремента
++/--вызывают геттер только один раз и кэшируют значение, чтобы избежать побочных эффектов.
/// Прямоугольник экранной системы координат, начало координат (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 Абстрактные методы
- Определяют только интерфейс, не имеют тела функции, вместо реализации используется точка с запятой
;; - Могут располагаться только в
abstract classабстрактных классах или миксинах (mixin); - Подклассы должны переопределить и реализовать все абстрактные методы, иначе подкласс тоже нужно пометить как
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 | Экземплярный метод с специальным именем, ключевое слово operator | operator +() и другие | Пользовательские сложение, вычитание, индексация и сравнение объектов на равенство |
| Getter/Setter | Чтение/запись свойств; get без параметров, set с одним параметром | get / set | Инкапсуляция вычисляемых свойств, единая точка чтения и записи извне |
| Абстрактный метод Abstract | Без тела метода, только объявление интерфейса | Точка с запятой ; после сигнатуры | Задание спецификации в абстрактном родительском классе, принудительная реализация в подклассах |