Menu
CoddyTech

取值方法与设值方法

本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 21 课,共 110 课。

获取器和设置器提供了一种通过特殊方法访问和修改类字段的方式,这些方法看起来像普通属性。你可以控制值的读取和写入方式,而不是直接公开字段。

获取器使用 get 关键字定义,并返回计算得出或存储的值:

class Rectangle {
  double width;
  double height;
  
  Rectangle(this.width, this.height);
  
  double get area => width * height;
  double get perimeter => 2 * (width + height);
}

Rectangle rect = Rectangle(5, 3);
print(rect.area);      // 15.0
print(rect.perimeter); // 16.0

注意,area 和 perimeter 的访问方式和字段一样,但它们每次都会重新计算。不需要加括号。

setter 使用 set 关键字,让你可以控制值的赋值方式:

class Temperature {
  double _celsius;
  
  Temperature(this._celsius);
  
  double get celsius => _celsius;
  set celsius(double value) {
    if (value >= -273.15) {
      _celsius = value;
    }
  }
  
  double get fahrenheit => _celsius * 9 / 5 + 32;
  set fahrenheit(double value) {
    celsius = (value - 32) * 5 / 9;
  }
}

Temperature temp = Temperature(25);
print(temp.fahrenheit);  // 77.0
temp.fahrenheit = 100;
print(temp.celsius);     // 37.78

setter 会在存储输入前对其进行验证,甚至可以进行单位换算。这样,你既能控制数据,又能让类的使用者通过简洁、类似属性的语法来操作数据。

challenge icon

挑战

简单

让我们为一款游戏创建一个分数跟踪器,使用 getter 和 setter 管理玩家统计数据,并进行验证和计算属性值。

你将把代码分成两个文件:

  • player.dart:定义一个用于跟踪玩家游戏表现的 Player 类。类中应包含:
    • 一个 String name 字段,用于保存玩家的名字
    • 一个初始值为 0 的私有 int _score 字段
    • 一个初始值为 3 的私有 int _lives 字段
    • 一个接收玩家名字的构造函数
    • 一个返回当前分数的 getter score
    • 一个只接受大于或等于 0 的值的 setter score(忽略负数)
    • 一个返回当前生命数的 getter lives
    • 一个只接受 0 到 5(包含两端)之间的值的 setter lives(忽略超出此范围的值)
    • 一个 getter level,根据分数计算玩家等级:分数除以 100(整数除法),再加 1
    • 一个 getter isAlive,当生命数大于 0 时返回 true
    • 一个用于打印玩家当前状态的 displayStatus() 方法
  • main.dart:导入你的玩家类,并演示 getter 和 setter:
    • 创建一个名为 'Alex' 的玩家
    • 将分数设为 250,并调用 displayStatus()
    • 尝试将分数设为 -50(应被忽略),并调用 displayStatus()
    • 将生命数设为 1,并调用 displayStatus()
    • 尝试将生命数设为 10(应被忽略),并调用 displayStatus()

displayStatus() 方法应严格按照以下格式打印:

[name] | Score: [score] | Level: [level] | Lives: [lives] | Alive: [isAlive]

预期输出:

Alex | Score: 250 | Level: 3 | Lives: 3 | Alive: true
Alex | Score: 250 | Level: 3 | Lives: 3 | Alive: true
Alex | Score: 250 | Level: 3 | Lives: 1 | Alive: true
Alex | Score: 250 | Level: 3 | Lives: 1 | Alive: true

亲手试试

import 'player.dart';

void main() {
  // TODO: 创建一个名为 'Alex' 的玩家

  // TODO: 将分数设置为 250,然后调用 displayStatus()

  // TODO: 尝试将分数设置为 -50(应该被忽略),然后调用 displayStatus()

  // TODO: 将生命数设置为 1,然后调用 displayStatus()

  // TODO: 尝试将生命数设置为 10(应该被忽略),然后调用 displayStatus()
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Dart 在线编译器