第 6 课 · 约 14 分钟 · ← 第 5 课

类与对象:带行为的数据

类是图纸;对象是按图纸造出来的东西。类类型的变量持有指向那个东西的引用。三个概念:字段装数据,构造器完成初始化,方法做动作。

一个什么都有类

class BankAccount
{
    public string Owner;                 // 字段:每个对象一份

    public BankAccount(string owner)     // 构造器:在 new 时运行
    {
        Owner = owner;
    }

    public void Print()
    {
        Console.WriteLine(Owner);
    }
}

BankAccount acct = new BankAccount("Ada");   // 造它
acct.Print();

逐块拆:public = 类外可见。构造器和类同名、没有返回类型——它的职责是让对象一出生就合法。new 分配内存并运行它。

每个对象都是自己的

class Dog
{
    public string Name;

    public Dog(string name) { Name = name; }
}

Dog a = new Dog("Ada");
Dog b = new Dog("Grace");
Console.WriteLine(a.Name);
Console.WriteLine(b.Name);        // 两个对象,两个 Name——不共享

static:属于类,不属于对象

class Counter
{
    public static int Total = 0;      // 只有一份,全员共享

    public static void Increment()
    {
        Total++;
    }
}

Counter.Increment();                 // 在类上调用——不需要对象
Counter.Increment();
Counter.Increment();
Console.WriteLine(Counter.Total);

你早就在用 static 成员了:Console.WriteLine、int.Parse、Math.Max——全是类上的方法,不涉及对象。经验法则:工具方法和共享计数器用 static;"每个一份"的用实例。

属性:长着公众面孔的字段

现代 C# 风格——自动属性看起来像字段,但它是正式成员,带 get/set:

class Rectangle
{
    public double Width { get; set; }     // 自动属性
    public double Height { get; set; }

    public double Area()
    {
        return Width * Height;            // 不用写 this. —— 默默补上
    }
}

Rectangle r = new Rectangle { Width = 3, Height = 4 };   // 对象初始化器
Console.WriteLine(r.Area());

对象初始化器(new Rectangle { … })在构造后立刻设属性——简单的初始化不需要参数构造器。

this:名字撞车的时候

在实例代码里,this 意思是"当前这个对象"。它的主业:区分参数和同名字段:

class Dog
{
    private string name;

    public Dog(string name)
    {
        this.name = name;   // this.name = 字段;name = 参数
    }
}

风格建议:字段用 PascalCase(Name)或前缀(_name),this. 就几乎永远用不上——一个代码库选定一种惯例就好。

构造器出错的样子

只要你声明了任何构造器,C# 就不再免费提供空的那个——new Person() 会报 CS1729。修法:要么传参数,要么显式补一个无参构造器。

现在就练