用于封装的属性
本课属于 Coddy C# 学习旅程的“面向对象编程”单元。第 32 课,共 70 课。
属性是在 C# 中实现封装的主要工具。你可以用属性包装字段,而不是直接公开字段,从而控制数据的访问和修改方式。
这种模式将私有字段与公共属性结合起来,并在访问器中加入验证或逻辑:
public class Temperature
{
private double celsius;
public double Celsius
{
get { return celsius; }
set
{
if (value < -273.15)
celsius = -273.15; // 最低为绝对零度
else
celsius = value;
}
}
}现在,外部代码无法设置无效的温度。这个属性就像把关者,确保你的对象始终处于有效状态。这就是封装的实际应用:内部数据受到保护,同时仍可通过受控接口访问。
你还可以使用属性来计算值或触发副作用:
public double Fahrenheit
{
get { return celsius * 9 / 5 + 32; }
set { celsius = (value - 32) * 5 / 9; }
}外部世界能看到两个属性,但内部实际上只有一个字段。属性可以让你在不破坏使用你的类的代码的前提下更改实现细节,这是良好封装的一大优势。
挑战
简单让我们构建一个使用属性来保护数据完整性的产品库存系统。你将创建一个类,确保价格不会变成负数,数量始终处于有效范围内,展示属性如何充当数据的守门员。
你需要将代码分成两个文件:
Product.cs:在Inventory命名空间中创建一个Product类,通过属性管理产品信息并进行验证。你的产品需要包含:- 一个私有字段
price(decimal),以及一个公共属性Price,确保价格不会低于0。如果有人尝试设置负价格,则应将其存储为0 - 一个私有字段
quantity(int),以及一个公共属性Quantity,确保值介于0和1000之间。低于 0 的值变为 0,高于 1000 的值变为 1000 - 一个公共自动实现属性
Name(string) - 一个只读计算属性
TotalValue,返回Price * Quantity
- 一个私有字段
Program.cs:在主文件中,使用输入值创建一个Product。然后尝试使用额外的输入值修改价格和数量,这些值可能无效。分别在创建后和每次修改后打印产品状态,看看属性如何保护数据。
你将收到 5 个输入:
- 产品名称
- 初始价格(decimal)
- 初始数量(整数)
- 要设置的新价格(decimal,可能为负数)
- 要设置的新数量(整数,可能超出范围)
按以下格式打印输出:
After creation:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
After modifications:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}例如,如果输入是 Laptop、999.99、50、-100 和 1500,输出应为:
After creation:
Laptop: Price=999.99, Qty=50, Total=49999.50
After modifications:
Laptop: Price=0, Qty=1000, Total=0注意,负价格变成了 0,数量 1500 被限制为 1000。你的属性正在保护对象,使其不会处于无效状态,这就是封装的作用!
亲手试试
using System;
using Inventory;
class Program
{
public static void Main(string[] args)
{
// 读取输入
string name = Console.ReadLine();
decimal initialPrice = Convert.ToDecimal(Console.ReadLine());
int initialQuantity = Convert.ToInt32(Console.ReadLine());
decimal newPrice = Convert.ToDecimal(Console.ReadLine());
int newQuantity = Convert.ToInt32(Console.ReadLine());
// TODO: 使用初始值创建一个 Product 对象
// TODO: 输出创建后的产品状态
Console.WriteLine("After creation:");
// 输出格式:{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
// TODO: 用新值修改价格和数量
// TODO: 输出修改后的产品状态
Console.WriteLine("After modifications:");
// 输出格式:{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C# 在线编译器