Геттеры и сеттеры

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

Приватные поля позволяют скрыть от внешнего кода состояние объекта. Однако нередко бывает необходимо иметь доступ к этим полям. Геттеры и сеттеры позволяют объединить приватность полей и возможность доступа к ним из внешнего кода, обеспечить контроллируемый доступ к приватным полям.

Например, возьмем следующий класс Person

class Person{

	String _name;   // приватное поле name
	int _age;        // приватное поле age
	
    Person(this._name, this._age);
}

Здесь приватность позволяет избежать установки полям _name и _age некорректных значений, например, пустой строки для имени или отрицательного возраста. Однако было бы неплохо, если бы могли установить корректные значения либо просто получить значения. И геттеры и сеттеры могут в этом помочь.

Геттеры

Геттеры (getters) предназначены для возвращения значения. Геттер представляет специальный метод, который использует ключевое слово get перед названием свойства и возвращает некоторое значение:

class Person{

	String _name;   // приватное поле name
	int _age;        // приватное поле age

    String get name {return _name;}
    int get age {return _age;}
	
    Person(this._name, this._age);
}

Здесь определено два геттера:

String get name {return _name;}
int get age {return _age;}

Геттер начинается с возвращаемого типа, после которого следует ключевое слово get и имя свойства. А после имени свойства идет блок кода, где собственно возвращается значение. Причем никаких параметров подобный метод не принимает. В данном случае имя свойства соответствует имени поля (за исключением начального подчеркивания), значение которого возвращается, но это необязательно.

То есть у нас здесь два геттера: свойство name возвращает значение поля _name, а свойство age возвращает значение поля _age.

Далее в функции main мы можем обратиться к этим свойствам:

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

void main() {

    Person tom = Person("Tom", 38);
    print(tom.name);    // Tom
    print(tom.age);     // 38
}

Причем через геттер можно только получить значение, а установить нельзя.

Стоит отметить, что если геттер имеет одну строку кода, то, как и любой другой метод, его можно сократить:

String get name =>_name;
int get age => _age;

Сеттеры

Сеттеры позволяют установить значение поля. Сеттер представляет специальный метод, который начинается с ключевого слова set, за которым следует название свойства. Затем идет один параметр, который представляет устанавливаемое значение:

set имя_свойство(параметр) { тело сеттера}

Например, определим в классе Person сеттер для установки поля _age:

class Person{

	String _name;   // приватное поле name
	int _age;        // приватное поле age

    String get name =>_name;
    int get age => _age;
    // сеттер
    set age(int value){
        if(value > 0 && value < 111){     // если age в диапазоне от 1 до 110
            _age = value;
        }
    }
	
    Person(this._name, this._age);
}

Сеттер представляет свойство age. Поскольку нам надо установить значение значение поля _age, то параметр сеттера представляет тип int:

set age(int value){
    
    if(value > 0 && value < 111){
         _age = value;
    }
}

В сеттере проверяем устанавливаемое значение. Если оно представляет действительный разумный возраст - от 1 до 110, то изменяем значение поля _age. Если же переданное значение некорректно, то оно никак не сказывается на поле _age. Таким образом, мы можем предоставить контролируемый доступ извне к полю _age.

Теперь мы сможем изменить значение свойства age (фактически поля _age):

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

void main() {

    Person tom = Person("Tom", 38);
    tom.age = 22;       // вызываем сеттер
    print(tom.age);     // 22
    tom.age = 100500;   // вызываем сеттер
    print(tom.age);     // 22
}

При передаче свойству age значения, срабатывает сеттер. И если это значение корректное, то сеттер изменяет поле _age:

tom.age = 22;       // вызываем сеттер
print(tom.age);     // 22

Если передается некорректное значение, то ничего не изменяется:

tom.age = 100500;   // вызываем сеттер
print(tom.age);     // 22

Вычисляемые свойства

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

class Person{

	String _name;   // приватное поле name
	int _age;        // приватное поле age

    String get name =>_name;
    int get age => _age;
    
    // вычисляемое свойства
    bool get isChild => _age < 18;
	
    Person(this._name, this._age);
}

Здесь в класс Person добавлено вычисляемое свойство isChild, которое возвращает true, если текущий объект Person условно является ребенком - если ему меньше 18 лет.

bool get isChild => _age < 18;

Далее это свойство можно использовать как и другие свойства-геттеры:

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

void main() {

    Person tom = Person("Tom", 38);
    bool tomIsChild = tom.isChild;          // вызываем вычисляемое свойство isChild
    print("Tom is child? $tomIsChild");     // Tom is child? false
    

    Person sam = Person("Sam", 16);
    bool samIsChild = sam.isChild;
    print("Sam is child? $samIsChild");     // Sam is child? true
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850