我想知道它是否有目的地设计为能够在编写类方法时使用两种不同的方式,其中引用了实例属性,这听起来可能很模糊,所以我提供了一个小代码片段来说明我的观点。
起初,我觉得我们使用this.age
而不是age
,因为后者会修改所有实例的age
属性,但当我尝试使用&在没有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
}
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.
}
"this关键字用于引用当前类对象。它指示类、方法或构造函数的当前实例。它还可以用来调用当前的类方法或构造函数。它消除了类属性和参数名称之间的不确定性。如果我们声明类属性与参数名称相同,这种情况将在程序中产生歧义,那么this关键字可以通过在类属性前面加前缀来消除歧义。它可以作为类方法或构造函数中的参数传递">
简而言之,Dart将搜索一个名为"的类属性;年龄;如果你不使用这个。
如果您的函数已经声明了一个名为"的变量;年龄;dart将引用该变量。要引用类属性,现在可以使用关键字
更改实例的类属性不会影响其他实例的属性。它和这个关键字并没有任何关系。这只是OOP的一个原则,其他OOP语言也是如此。
你的foo和bar是Person 的完全独立的实例