Dart 中的 getter 和 setter

在 Dart 中,gettersetter 是用于访问对象的属性的特殊方法。通过 getter 和 setter,你可以控制如何读取和修改对象的属性,这为对象提供了更高的封装性和灵活性。

一、 Getter(获取器)

Getter 用于获取对象的属性值。它是一个特殊的方法,通过 get 关键字来定义,通常用来让外部访问对象的私有属性。getter 允许你通过像访问字段一样访问方法,但实际上它是执行方法逻辑来返回值。

例子:
class Person {
    
    
  String? _name;
  Person(this._name);
  // Getter
  String? get name =>_name;
  // 如果不希望外部代码直接修改,可以提供只读的getter
}

void main() {
    
    
  var person = Person('Alice');
  print(person.name);  // 通过 getter 访问
  //person.name = "siri"; //报错不能修改
}

在这个例子中,name 就是一个 getter,你可以像访问字段一样访问它,但实际上它是通过 _name 属性来获取数据的。

二、Setter(设置器)

Setter 用于设置对象的属性值。它是一个特殊的方法,通过 set 关键字来定义。setter 通常用于在设置对象的属性时进行额外的逻辑处理,如验证输入、修改值等。

例子:

class Person {
    
    
  String? _name;
  Person(this._name);
  // Getter
  String? get name =>_name;

  // Setter _name 是可空的 设置值时也必须时可空的 String? 可以省略不写 写了就一定要带?
  set name(String? value) {
    
    
    if (value.isEmpty) {
    
    
      print('Name cannot be empty');
    } else {
    
    
      _name = value;
    }
  }
}

void main() {
    
    
  var person = Person('Alice');
  print(person.name);  // 使用 getter 访问

  // 使用 setter 设置值
  person.name = 'Bob';  // 通过 setter 设置
  print(person.name);  // 输出 Bob

  person.name = '';  // 输出 Name cannot be empty
}

在上面的例子中,name 既有 getter 又有 setter。getter 用来获取 _name 属性的值,而 setter 用来设置 _name 的值,同时添加了一些逻辑来确保名字不会为空。

简化的 Setter

在 Dart 中,你也可以为单一属性创建简化版的 getter 和 setter,这样写法更加简洁。

例子:

class Person {
    
    
  String? _name;

  Person(this._name);

  // Getter
  String? get name => _name;

  // 简化版 Setter
  set name(String? value) => _name = value;
}

void main() {
    
    
  var person = Person('Alice');
  print(person.name);  // 输出 Alice

  person.name = 'Bob';  // 设置新名字
  print(person.name);  // 输出 Bob
}

这个例子中使用了 Dart 提供的简化语法,代码更加简洁。

三、只读 Getter 和只写 Setter

你可以选择只实现 gettersetter,从而使某个属性只能被读取或只能被设置。

只读 Getter:

class Person {
    
    
  String? _name;

  Person(this._name);

  // 只读 getter
  String? get name => _name;
}

void main() {
    
    
  var person = Person('Alice');
  print(person.name);  // 只可以读取 name person.name = "..." 会报错
}

只写 Setter:

class Person {
    
    
  String? _name;

  Person(this._name);

  // 只写 setter
  set name(String? value) => _name = value;
}

void main() {
    
    
  var person = Person('Alice');
  person.name = 'Bob';  // 只可以设置 name
  print(person.name); //读取会报错
}

四、getter 和 setter 的用法场景

  • 数据封装:通过 getter 和 setter,可以控制访问和修改数据的方式,保护内部实现的细节,避免外部直接修改对象的私有属性。
  • 输入验证:在 setter 中,可以添加逻辑来验证输入数据的有效性。
  • 延迟计算:有时你不希望在属性访问时直接存储数据,而是根据其他字段的值动态计算一个值,这时可以使用 getter 来实现延迟计算。

例子:计算属性

class Rectangle {
    
    
  double width, height;

  Rectangle(this.width, this.height);

  // 计算属性:面积(不需要存储,动态计算)
  double get area => width * height;
}

void main() {
    
    
  var rectangle = Rectangle(5, 10);
  print(rectangle.area);  // 输出 50
}

在上面的例子中,area 并不是一个实际存储的属性,而是通过 widthheight 计算得出的。这是一个典型的使用 getter 进行计算的例子。

总结

  • getter 用于返回对象的属性值,它通过 get 关键字定义。
  • setter 用于设置对象的属性值,它通过 set 关键字定义。
  • getter 是只读的 setter 是只写的。

猜你喜欢

转载自blog.csdn.net/weixin_40323532/article/details/144951043
今日推荐