实例数据与静态数据
本课属于 Coddy C# 学习旅程的“面向对象编程”单元。第 15 课,共 70 课。
现在你已经了解了静态成员,让我们来明确何时使用实例数据,何时使用静态数据。这个决定会影响类如何存储和共享信息。
实例数据分别属于每个对象。每个对象都有自己的副本,对一个对象的更改不会影响其他对象:
public class BankAccount
{
public string Owner { get; set; } // 实例属性,每个账户各有一个
public decimal Balance { get; set; } // 实例属性,每个账户各有一个
}每个 BankAccount 都有自己的所有者和余额。这很合理,因为不同账户属于不同的人,金额也各不相同。
静态数据属于类本身,并由所有实例共享:
public class BankAccount
{
public static decimal InterestRate = 0.05m; // 静态字段,所有账户共用
public static int TotalAccounts = 0; // 静态字段,统计所有账户
public string Owner { get; set; }
public decimal Balance { get; set; }
}利率对每个账户都相同,因此将其设为静态是合理的。账户总数计数器跟踪的是整个类的信息,而不是单个账户的数据。
一个简单的规则:如果数据描述的是某个特定对象,就把它设为实例属性。如果数据描述的是整个类,或者应该由多个对象共享,就把它设为静态属性。混淆两者会导致 bug,例如数据在不同对象之间意外改变,或在需要时无法访问。
挑战
简单让我们来构建一个游戏会话追踪器,展示每位玩家各自拥有的数据与整个游戏共享的数据之间的区别。
你将创建两个文件来组织代码:
Player.cs:在GameSession命名空间中定义一个Player类。每位玩家都有自己的Username(字符串)和Score(整数),这些数据对每位玩家来说都是独有的。这个类还应追踪适用于所有玩家的信息:一个静态字段GameName(字符串),用于存储所有人正在玩的游戏名称;以及一个静态字段TotalPlayers(整数),用于统计已加入的玩家人数。添加一个接收用户名和初始分数的构造函数,并自动增加玩家总数。添加一个静态方法SetGameName(string name)来设置游戏名称。Program.cs:在主文件中设置游戏,并根据输入创建玩家。先设置游戏名称,然后创建两位玩家,并显示他们各自的信息以及共享的游戏数据。
你将收到 5 个输入:
- 游戏名称
- 第一位玩家的用户名
- 第一位玩家的初始分数
- 第二位玩家的用户名
- 第二位玩家的初始分数
按以下格式打印输出:
Game: {GameName}
Player: {Username}, Score: {Score}
Player: {Username}, Score: {Score}
Total Players: {TotalPlayers}例如,如果输入是 BattleArena、DragonSlayer、1500、ShadowNinja 和 2200,输出应为:
Game: BattleArena
Player: DragonSlayer, Score: 1500
Player: ShadowNinja, Score: 2200
Total Players: 2仔细想想哪些数据应基于实例(每位玩家各不相同),哪些数据应是静态的(由所有玩家共享)。游戏名称和玩家总数描述的是整个会话,而用户名和分数则是每位玩家独有的。
亲手试试
using System;
namespace GameSession
{
class Program
{
public static void Main(string[] args)
{
// 读取输入
string gameName = Console.ReadLine();
string username1 = Console.ReadLine();
int score1 = Convert.ToInt32(Console.ReadLine());
string username2 = Console.ReadLine();
int score2 = Convert.ToInt32(Console.ReadLine());
// TODO: 使用静态方法设置游戏名称
// TODO: 使用输入数据创建两个 Player 对象
// TODO: 按要求的格式打印输出
// Game: {GameName}
// Player: {Username}, Score: {Score}
// Player: {Username}, Score: {Score}
// Total Players: {TotalPlayers}
}
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C# 在线编译器