Menu
Coddy logo textTech

Статические методы и поля

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

Теперь, когда вы понимаете разницу между членами экземпляра и статическими членами, давайте изучим, как эффективно использовать статические методы и поля. Статические члены идеально подходят для функциональности, которая относится к самой концепции класса, а не к отдельным объектам.

Статические поля хранят данные, общие для всех экземпляров. Типичные варианты использования включают счетчики, значения конфигурации или кэшированные данные:

class MathHelper {
  static const double pi = 3.14159;
  static int calculationCount = 0;
  
  static double circleArea(double radius) {
    calculationCount++;
    return pi * radius * radius;
  }
}

print(MathHelper.circleArea(5));  // 78.53975
print(MathHelper.circleArea(3));  // 28.27431
print(MathHelper.calculationCount);  // 2

Обратите внимание, что вы вызываете статические методы непосредственно через имя класса, а не через экземпляр. Класс MathHelper работает как утилита — вам никогда не нужно создавать объект MathHelper.

Важное правило: статические методы не могут напрямую обращаться к членам экземпляра. Они не имеют доступа к this, потому что они не привязаны к какому-либо конкретному объекту:

class Counter {
  int value = 0;  // Поле экземпляра
  static int total = 0;  // Статическое поле
  
  void increment() {
    value++;  // OK — метод экземпляра обращается к полю экземпляра
    total++;  // OK — метод экземпляра может обращаться к статическому полю
  }
  
  static void reset() {
    total = 0;  // OK — статический метод обращается к статическому полю
    // value = 0;  // Ошибка! Невозможно обратиться к полю экземпляра
  }
}

Используйте статические члены, когда функциональность не зависит от состояния объекта — утилитарные функции, отслеживание фабрик или общие константы являются идеальными кандидатами.

challenge icon

Задание

Легко

Давайте создадим утилитарный класс для строковых операций, который демонстрирует, как статические методы и поля работают вместе, обеспечивая полезную функциональность без необходимости создания объектов.

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

  • string_utils.dart: Определите класс StringUtils, который служит вспомогательной утилитой. Ваш класс должен иметь:
    • static const String defaultSeparator, установленный в '-'
    • static int operationCount, начинающийся с 0, для отслеживания количества выполненных операций
    • Статический метод reverse(String text), который увеличивает operationCount и возвращает перевернутую строку
    • Статический метод join(String first, String second), который увеличивает operationCount и возвращает две строки, соединенные через defaultSeparator
    • Статический метод countVowels(String text), который увеличивает operationCount и возвращает количество гласных (a, e, i, o, u — без учета регистра)
    • Статический метод getStats(), который возвращает строку, показывающую общее количество выполненных операций
  • main.dart: Импортируйте ваш утилитарный класс и используйте его статические методы:
    • Вызовите reverse() с аргументом 'hello' и выведите результат
    • Вызовите join() с аргументами 'dart' и 'lang' и выведите результат
    • Вызовите countVowels() с аргументом 'Programming' и выведите Vowels: [count]
    • Выведите статистику, используя getStats()

Не забудьте вызывать все методы непосредственно через имя класса, так как они статические — вам не нужно создавать объекты StringUtils.

Метод getStats() должен возвращать данные в таком формате:

Operations performed: [operationCount]

Ожидаемый вывод:

olleh
dart-lang
Vowels: 3
Operations performed: 3

Шпаргалка

Статические члены принадлежат самому классу, а не отдельным экземплярам. Обращайтесь к ним, используя имя класса, а не объект.

Статические поля хранят данные, общие для всех экземпляров:

class MathHelper {
  static const double pi = 3.14159;
  static int calculationCount = 0;
  
  static double circleArea(double radius) {
    calculationCount++;
    return pi * radius * radius;
  }
}

print(MathHelper.circleArea(5));  // 78.53975
print(MathHelper.calculationCount);  // 1

Правила доступа:

  • Методы экземпляра могут обращаться как к членам экземпляра, так и к статическим членам
  • Статические методы могут обращаться только к статическим членам (нет доступа к this)
class Counter {
  int value = 0;  // Поле экземпляра
  static int total = 0;  // Статическое поле
  
  void increment() {
    value++;  // OK - метод экземпляра обращается к полю экземпляра
    total++;  // OK - метод экземпляра может обращаться к статическому полю
  }
  
  static void reset() {
    total = 0;  // OK - статический метод обращается к статическому полю
    // value = 0;  // Ошибка! Невозможно обратиться к полю экземпляра
  }
}

Используйте статические члены для вспомогательных функций, общих констант, счетчиков или функциональности, которая не зависит от состояния объекта.

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

import 'string_utils.dart';

void main() {
  // TODO: Вызовите reverse() с 'hello' и выведите результат
  
  // TODO: Вызовите join() с 'dart' и 'lang' и выведите результат
  
  // TODO: Вызовите countVowels() с 'Programming' и выведите "Vowels: [count]"
  
  // TODO: Выведите статистику, используя getStats()
}
quiz iconПроверьте себя

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

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