#dart
#dart
Вопрос:
Мне было интересно, был ли он специально разработан, чтобы иметь возможность использовать два разных способа написания методов класса, внутри которых ссылается свойство экземпляра, это может показаться расплывчатым, поэтому я предоставил небольшой фрагмент кода, чтобы проиллюстрировать свою точку зрения.
Сначала у меня создалось впечатление, что мы используем this.age
вместо age
, потому что последнее изменит все свойство instances age
, но когда я попробовал с amp; без this.
ключевого слова, он изменил только экземпляр, для которого changeAge
используется метод.
Есть ли цель иметь два способа написания этого?
class Person{
String name;
int age;
Person({this.name, this.age});
void changeAge(int a){
this.age = a; // why can this be written: age = a; and achieve same result?
}
}
void main(){
Person foo = Person(name: 'foo', age: 16);
Person bar = Person(name: 'bar', age: 30);
foo.changeAge(99);
print(foo.age); // prints 99
print(bar.age); // prints 30
}
Ответ №1:
Dart использует лексическую область для поиска значения идентификаторов. Когда вы пишете age
, компилятор:
- Сначала проверяет, есть ли имена локальных переменных
age
в текущей функции. - Затем он проверяет, есть ли параметр или параметр типа для названной функции
age
. - Затем он проверяет, есть ли объявление с именем
age
в окружающем классе (которое есть вPerson
). Это может быть либо объявление экземпляра, либо статическое объявление. - Затем он проверяет наличие параметра типа имени класса
age
, если класс является универсальным. - Затем он проверяет текущую библиотеку на наличие объявления верхнего уровня с именем
age
. - Затем он проверяет наличие импортированного объявления с именем
age
.
Если он находит какое-либо объявление, то считает age
, что оно ссылается на это. Если то, что он нашел, было статическим объявлением, то age
эквивалентно ClassName.age
. Если он нашел объявление экземпляра, то age
эквивалентно this.age
.
Если он ничего не нашел, и он находится внутри метода экземпляра, то он обрабатывает age
как this.age
, и это ошибка, если в текущем классе нет унаследованного age
элемента экземпляра.
Итак, в этом случае причина age = a;
и this.age = a;
та же, что age
преобразуется в переменную экземпляра окружающего класса.
Вам не нужно писать this.age
, но вы можете, поэтому вы можете написать свой changeAge
метод как:
void changeAge(int age){
this.age = age; // `this.age` is the field, `age` refers to the parameter.
}
Ответ №2:
«Ключевое слово this используется для ссылки на текущий объект класса. Он указывает текущий экземпляр класса, методов или конструктора. Его также можно использовать для вызова текущих методов или конструкторов класса. Это устраняет неопределенность между атрибутами класса, а имена параметров одинаковы. Если мы объявляем атрибуты класса такими же, как имя параметра, эта ситуация создаст двусмысленность в программе, тогда ключевое слово this может устранить двусмысленность, добавив префикс к атрибутам класса. Он может быть передан в качестве аргумента в методе класса или конструкторах. «
Короче говоря, Dart будет искать свойство класса с именем «возраст», если вы не используете это.
Если ваша функция уже объявила переменную с именем «возраст», dart будет ссылаться на эту переменную. Чтобы вместо этого ссылаться на свойство класса, теперь вы можете использовать ключевое слово this
Изменение свойства класса экземпляра не повлияет на свойство других экземпляров. Это не имеет ничего общего с ключевым словом this . Это просто принцип ООП, он такой же на других языках ООП .
Ваши foo и bar являются полностью независимыми экземплярами Person