Статические члены классов

Последнее обновление: 04.04.2023

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

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

Статические поля хранят состояние всего класса. Статическое поле определяется как и обычное, только впереди ставится ключевое слово static. Например, рассмотрим класс Employee, который представляет работника:

class Employee{
	
	String name;
	int age;
	static int retirementAge = 60;	 // статическое поле
	
	Employee(this.name, this.age);
	
	checkAge(){
		if(age >= retirementAge){
			print("Пора на пенсию");
		}
		else{
			print("До пенсии еще ${retirementAge - age} лет");
		}
	}
}
void main (){
	
	Employee bob = Employee("Bob", 55);
	bob.checkAge();
	Employee.retirementAge = 65;	// меняем значение статического поля
	bob.checkAge();
}

В классе работника определены поля для хранения имени и возраста - у каждого отдельного работника может быть свое имя и свой возраст. Кроме того, определено статическое поле для хранения пенсионного возраста retirementAge. Оно относится не к конкретному работнику, а ко всем работникам, то есть ко всему классу Employee в целом, так как нельзя для каждого отдельного работника установить свою пенсионную группу. Затем в самом классе мы можем использовать это поле как и любые другие.

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

Employee.retirementAge = 65;

В чем преимущества статических полей и методов перед нестатическими? Статические поля и методы потребляют меньше памяти, чем нестатические. Нестатическая переменная после инициализации (при первом присвоении значения) сразу начинает потреблять память независимо от того, используется она или нет. А статические поля и методы не инициализируются до того момента, пока они не начнут использоваться в программе. Соответственно потреблять память они начинают только тогда, когда непосредственно начинают использоваться.

Статические константы

Если пенсионный возраст менять не планируется, то мы можем определить как статическую константу:

class Employee{
	
	String name;
	int age;
	static const int retirementAge = 65;
	
	Employee(this.name, this.age);
	
	checkAge(){
		if(age >= retirementAge){
			print("Пора на пенсию");
		}
		else{
			print("До пенсии еще ${retirementAge - age} лет");
		}
	}
}
void main (){
	
	Employee bob = Employee("Bob", 55);
	bob.checkAge();
	print("Retirenment age: ${Employee.retirementAge}");
}

Для определения статической константы применяется выражение static const:

static const int retirementAge = 65;

Соответственно далее в программе мы не можем изменить ее значение.

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

Статические методы также относятся ко всему классу и предваряются ключевым словом static. Как правило, статические методы выполняют такие вычисления, которые не затрагивают состояние или поведение объекта:

void main (){
	
	int a = Operation.sum(3, 5);
	int b = Operation.subtract(15, 7);
	int c = Operation.multiply(3, 5);
	print("a=$a  b=$b  c=$c");	// a=8  b=8  c=15
}
class Operation{
     
    static int sum(int x, int y) => x + y; 
    static int subtract(int x, int y) => x - y;
    static int multiply(int x, int y) => x * y;
}

В данном случае для методов sum, subtract, multiply не имеет значения, какой именно экземпляр класса Operation используется. Эти методы работают только с параметрами, не затрагивая состояние класса. Поэтому их можно определить как статические.

Статические методы могут использоваться для управления доступом к статическим приватным полям, то есть состоянием, которое относится ко всему классу. В то же время в статических методах мы не можем использовать нестатические методы и поля класса. Например, пусть у нас есть следующий класс Person, который размещен в файле person.dart:

class Person{

	String _name;
	int _id = 0; 
    static int _count = 0;

    Person(this._name){

        _count += 1;
        _id = _count;
    }
    void display(){
        print("Id: $_id \tName: $_name");
    }
	// статический метод
    static int getCount() => _count;
}

В данном случае в классе Person определены три приватных поля. Два поля нестатические - _name и _id, который представляют соответственно имя и уникальный идентификатор человека. И одно поле статическое - count - оно будет хранить количество созданных объектов Person. Это количество относится ко всему классу в целом, не зависит от конкретного объекта, поэтому определенно как статическое.

В конструкторе при создании объекта мы увеличиваем значение count на 1 и присваиваем это значение полю _id. Таким образом, у каждого объекта Person будет уникальный числовой идентификатор.

И также в классе определен статический метод getCount, который возвращает значение статической переменной count. Таким образом, благодаря приватности поля мы не можем изменить произвольным образом его значение. И в то же время благодаря методу getCount мы можем получить его значение.

Далее в программе мы можем использовать этот статический метод, чтобы получить количество созданных объектов

import 'person.dart'; // подключаем файл с классом Person

void main (){
     
    Person tom = Person("Tom");
    Person bob = Person("Bob");
    Person sam = Person("Sam");

    tom.display();
    bob.display();
    sam.display();

    // получаем количество созданных объектов Person
    int personCount = Person.getCount();
    print("Person count: $personCount");
}

Консольный вывод программы

Id: 1   Name: Tom
Id: 2   Name: Bob
Id: 3   Name: Sam
Person count: 3

Статические свойства

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

class Person{

	String _name;
	int _id = 0; 
    static int _count = 0;

    Person(this._name){

        _count += 1;
        _id = _count;
    }
    void display(){
        print("Id: $_id \tName: $_name");
    }
	// статический геттер
    static int get count => _count;
}

Для обращения к статическим геттерам/сеттерам применяется имя класса:

import 'person.dart';	// подключаем класс Person

void main (){
     
    Person tom = Person("Tom");
    Person bob = Person("Bob");
    Person sam = Person("Sam");

    tom.display();
    bob.display();
    sam.display();

    // обращаемся к статическому геттеру
    int personCount = Person.count;
    print("Person count: $personCount");
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850