404 Not Found

404 Not Found


nginx

类与对象

为什么需要类

C# 是一门面向对象的语言,几乎一切皆对象。之前我们用顶层语句写代码,但真正的 C# 程序都由类构成。类是对象的蓝图——定义了数据(字段)和行为(方法),而对象是类的具体实例。

类的定义

class 关键字定义类,类名使用帕斯卡命名法(每个单词首字母大写)。

CSHARP
class Person
{
    public string Name;
    public int Age;

    public void SayHello()
    {
        System.Console.WriteLine($"你好,我是{Name},今年{Age}岁。");
    }
}

对象的创建

new 关键字根据类创建对象:

CSHARP
Person p = new Person();
p.Name = "小明";
p.Age = 18;
p.SayHello();
TEXT
你好,我是小明,今年18岁。

每个 new 创建一个独立的对象,拥有自己的字段副本。

字段与字段初始化

字段可以在声明时直接赋初始值:

CSHARP
class Student
{
    public string Name = "未知";
    public int Score = 0;
}

若未赋初值,数值类型默认为 0,引用类型默认为 null

访问修饰符控制字段的可见性:

修饰符 含义
public 任何地方都可访问
private 仅类内部可访问(默认)

通常将字段设为 private,通过方法或属性控制访问。

示例

CSHARP
using System;

class BankAccount
{
    private decimal balance = 1000m;

    public void Deposit(decimal amount)
    {
        balance += amount;
        Console.WriteLine($"存入{amount},余额{balance}");
    }

    public void ShowBalance()
    {
        Console.WriteLine($"当前余额:{balance}");
    }
}

class Program
{
    static void Main()
    {
        BankAccount acc = new BankAccount();
        acc.ShowBalance();
        acc.Deposit(500m);
    }
}
▶ 试一试
TEXT
当前余额:1000
存入500,余额1500

方法

方法是类中定义的函数,描述对象的行为。方法可以访问同一个类中的字段:

CSHARP
class Calculator
{
    private int result = 0;

    public void Add(int value)
    {
        result += value;
    }

    public int GetResult()
    {
        return result;
    }
}

this 关键字

this 指向当前对象实例,最常见的用途是区分字段与同名参数:

CSHARP
class Person
{
    public string Name;
    public int Age;

    public Person(string Name, int Age)
    {
        this.Name = Name;
        this.Age = Age;
    }
}

构造函数

构造函数在创建对象时自动调用,用于初始化对象。

无参构造函数

如果不定义任何构造函数,编译器自动生成一个无参构造函数:

CSHARP
class Dog
{
    public string Name;

    public Dog()
    {
        Name = "无名";
    }
}

有参构造函数

CSHARP
class Dog
{
    public string Name;

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

⚠️ 一旦定义了任何构造函数,编译器不再自动生成无参构造函数。

构造函数重载

可以定义多个构造函数,参数不同:

CSHARP
class Dog
{
    public string Name;
    public int Age;

    public Dog()
    {
        Name = "无名";
        Age = 0;
    }

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

    public Dog(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

构造函数链

this(...) 让一个构造函数调用另一个,避免重复代码:

CSHARP
class Dog
{
    public string Name;
    public int Age;

    public Dog() : this("无名", 0) { }

    public Dog(string name) : this(name, 0) { }

    public Dog(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

示例

CSHARP
using System;

class Book
{
    public string Title;
    public string Author;
    public decimal Price;

    public Book() : this("未知", "未知", 0m) { }

    public Book(string title, string author) : this(title, author, 29.9m) { }

    public Book(string title, string author, decimal price)
    {
        Title = title;
        Author = author;
        Price = price;
    }

    public void PrintInfo()
    {
        Console.WriteLine($"《{Title}》 作者:{Author} 价格:{Price}元");
    }
}

class Program
{
    static void Main()
    {
        Book b1 = new Book();
        Book b2 = new Book("C#入门", "张三");
        Book b3 = new Book("深入C#", "李四", 59.9m);

        b1.PrintInfo();
        b2.PrintInfo();
        b3.PrintInfo();
    }
}
▶ 试一试
TEXT
《未知》 作者:未知 价格:0元
《C#入门》 作者:张三 价格:29.9元
《深入C#》 作者:李四 价格:59.9元

析构函数

析构函数在对象被垃圾回收前调用,语法为 ~类名()

CSHARP
class Resource
{
    ~Resource()
    {
        Console.WriteLine("对象被回收");
    }
}

📌 C# 有自动垃圾回收机制(GC),大多数情况不需要手动写析构函数。它只用于释放非托管资源(如文件句柄、数据库连接),后续课程会详细讨论。

对象初始化器

C# 3.0 引入的对象初始化器语法,可以在 new 时直接给公共字段或属性赋值:

CSHARP
Person p = new Person { Name = "小红", Age = 20 };

等价于:

CSHARP
Person p = new Person();
p.Name = "小红";
p.Age = 20;

对象初始化器可以与有参构造函数组合使用:

CSHARP
Person p = new Person("小红") { Age = 20 };

示例

CSHARP
using System;

class Rectangle
{
    public double Width = 1;
    public double Height = 1;

    public double Area()
    {
        return Width * Height;
    }
}

class Program
{
    static void Main()
    {
        Rectangle r1 = new Rectangle();
        Rectangle r2 = new Rectangle { Width = 5, Height = 3 };
        Rectangle r3 = new Rectangle { Width = 10 };

        Console.WriteLine($"r1 面积:{r1.Area()}");
        Console.WriteLine($"r2 面积:{r2.Area()}");
        Console.WriteLine($"r3 面积:{r3.Area()}");
    }
}
▶ 试一试
TEXT
r1 面积:1
r2 面积:15
r3 面积:10

new 与 null 的区别

概念 含义
new ClassName() 在堆上创建对象,返回对象引用
null 不指向任何对象,是引用类型的默认值
CSHARP
Person p1 = new Person();
Person p2 = null;

Console.WriteLine(p1 == null);
Console.WriteLine(p2 == null);
TEXT
False
True

⚠️ 对 null 引用访问成员会抛出 NullReferenceException,这是 C# 最常见的运行时错误:

CSHARP
Person p = null;
p.SayHello();

💡 使用前检查是否为 null

CSHARP
if (p != null)
{
    p.SayHello();
}

❓ 常见问题

Q 不写构造函数会怎样?
A 编译器自动生成一个无参构造函数,字段赋默认值。
Q 定义了有参构造函数后还能用无参创建对象吗?
A 不能,除非手动再定义一个无参构造函数。
Q this 能在静态方法中使用吗?
A 不能,this 指当前实例,静态方法不关联实例。
Q 对象初始化器能赋值 private 字段吗?
A 不能,只能初始化可访问的成员(public 字段或属性)。
Q null 和 0 是一回事吗?
A 不是。null 表示"无引用",0 是数值类型的值。值类型不能为 null。

📖 小节

📝 作业

  1. 定义一个 Car 类,包含 Brand(string)、Speed(int)字段,一个 Accelerate(int amount) 方法使 Speed 增加,一个无参构造函数将 Speed 初始化为 0
  2. Car 类添加有参构造函数 Car(string brand),并用 this(...) 实现构造函数链
  3. 用对象初始化器创建一个 Car 对象并设置 Brand 和 Speed,然后调用 Accelerate 方法,打印最终 Speed
  4. 编写代码演示:创建一个 Car 引用赋为 null,尝试访问其成员,用 try-catch 捕获 NullReferenceException 并打印提示信息
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏