一、类 -- class关键字
1. 声明一个类
在C#中,我们使用 class 关键字来定义一个类,也就是创建一份"蓝图"。
csharp
// 这就是一份最简单的"汽车蓝图"
// public 是一个访问修舍符,意味着这个蓝图在任何地方都可以被看到和使用
public class Car
{
// 类的成员将在这里定义...
}
恭喜你!你已经创建了你的第一个类。虽然它现在空无一物,但它已经是一个合法的C#类型了。
2. 添加类的成员
-
字段(Fields):数据的存储 字段是类内部用来存储数据的变量。通常,为了保护数据,我们会将字段声明为
private。csharppublic class Car { // 私有字段,用于存储汽车的颜色和当前速度 // 就像是内部零件,不对外直接暴露 private string _color; private int _speed; } -
方法(Methods):定义行为的"操作指南" 方法是定义类能做什么的函数。它们是对象的行为。
csharppublic class Car { // ... 字段 ... // 公开的方法,定义了汽车的行为 public void Accelerate() { _speed += 10; Console.WriteLine($"加速!当前速度: {_speed} km/h"); } public void Brake() { _speed -= 10; if (_speed < 0) _speed = 0; Console.WriteLine($"刹车!当前速度: {_speed} km/h"); } }
二、对象实例化 - new关键字
我们有了蓝图,现在需要根据它来建造一辆真正的汽车。这个过程叫做实例化(Instantiation) 。我们使用 new 关键字来创建类的实例,也就是对象。
csharp
// 声明一个 Car 类型的变量 myCar
// 并使用 new 关键字创建一个 Car 类的实例(对象),然后将其赋给 myCar
Car myCar = new Car();
// 再创建一辆车
Car yourCar = new Car();
// 现在,myCar 和 yourCar 就是两个独立的 Car 对象
// 它们都拥有自己的 _color 和 _speed 字段
// 调用 myCar 的方法,不会影响 yourCar
myCar.Accelerate(); // 输出: 加速!当前速度: 10 km/h
myCar.Accelerate(); // 输出: 加速!当前速度: 20 km/h
yourCar.Brake(); // 输出: 刹车!当前速度: 0 km/h
Console.WriteLine(myCar); // 输出类似: YourProjectName.Car
myCar和yourCar是两个引用,它们分别指向内存中两个不同的Car对象。每个对象都有自己独立的一套字段。
三、 类的剖析 - 深入理解核心成员
1. 构造函数(Constructors)
当你使用 new Car() 时,你实际上是在调用一个特殊的方法------构造函数。它的作用是在对象被创建时进行初始化工作,比如为字段设置初始值。
- 构造函数没有返回类型,连
void都没有。 - 它的名字必须与类名完全相同。
csharp
public class Car
{
private string _color;
private int _speed;
// 这是一个构造函数
// 它在 new Car("Red") 时被调用
public Car(string color)
{
// this 关键字代表当前正在被创建的对象实例
this._color = color;
this._speed = 0; // 设定初始速度为0
Console.WriteLine($"一辆{_color}的汽车被制造出来了!");
}
// ... 方法 ...
}
// === 使用构造函数创建对象 ===
Car redCar = new Car("红色"); // 输出: 一辆红色的汽车被制造出来了!
Car blueCar = new Car("蓝色"); // 输出: 一辆蓝色的汽车被制造出来了!
如果你不提供任何构造函数,C#编译器会自动为你生成一个无参数的、空的默认构造函数。
2. 属性(Properties)
我们之前将字段设为 private,这是封装原则的体现。但外界如何安全地读取或修改这些数据呢?答案是属性。
属性看起来像字段,但内部包含了get和set访问器,允许你编写逻辑来控制数据的读写。
csharp
public class Car
{
private string _color;
private int _speed;
// 为 _speed 字段创建一个名为 Speed 的公开属性
public int Speed
{
// get 访问器:当读取属性值时执行
get
{
return _speed;
}
// set 访问器:当给属性赋值时执行
set
{
// 'value' 是一个关键字,代表赋过来的值
if (value < 0)
{
Console.WriteLine("速度不能为负数!");
}
else
{
_speed = value;
}
}
}
// ... 构造函数和方法 ...
}
// === 使用属性 ===
Car myCar = new Car("银色");
myCar.Speed = 50; // 调用 set 访问器,将 50 赋给 value
Console.WriteLine($"当前速度: {myCar.Speed}"); // 调用 get 访问器
myCar.Speed = -10; // 调用 set 访问器,触发验证逻辑
// 输出: 速度不能为负数!
自动属性(Auto-Implemented Properties) 如果你的属性不需要任何特殊的get/set逻辑,C#提供了简洁的语法:
csharp
// 编译器会自动在后台创建一个名为<Color>k__BackingField的私有字段
public string Color { get; set; }
四、高级概念 - 深入类的本质
1. static:属于类,而非对象
默认情况下,类的成员(字段、方法等)都是实例成员 ,每个对象都有一份独立的副本。但有时,我们需要一些成员是所有对象共享的 ,或者说,是属于类本身 的。这时,我们使用 static 关键字。
csharp
public class Car
{
// 静态字段:所有Car对象共享这一个字段
public static int NumberOfCarsProduced = 0;
public string Color { get; set; }
public Car(string color)
{
this.Color = color;
NumberOfCarsProduced++; // 每制造一辆车,就让共享的计数器加一
}
// 静态方法:可以直接通过类名调用,无需创建对象
public static void DisplayProductionInfo()
{
Console.WriteLine($"总共生产了 {NumberOfCarsProduced} 辆汽车。");
}
}
// === 使用静态成员 ===
Car.DisplayProductionInfo(); // 输出: 总共生产了 0 辆汽车。
Car car1 = new Car("红色");
Car car2 = new Car("黑色");
Car.DisplayProductionInfo(); // 输出: 总共生产了 2 辆汽车。
2. 值类型(Value Types)与引用类型(Reference Types)
-
引用类型(
class):- 变量存储的是一个引用(地址),指向堆(Heap)内存中对象的实际位置。
- 将一个引用类型变量赋给另一个,只会复制引用,它们指向同一个对象。
csharpCar carA = new Car("红色"); Car carB = carA; // 复制引用,carA 和 carB 指向同一个对象 carB.Color = "蓝色"; Console.WriteLine(carA.Color); // 输出: 蓝色 -
值类型(
struct,int,double,bool等):- 变量直接存储数据本身,通常在栈(Stack)内存中。
- 将一个值类型变量赋给另一个,会创建数据的完整副本。
csharpint a = 10; int b = a; // 复制值,a 和 b 是两个独立的 10 b = 20; Console.WriteLine(a); // 输出: 10
五、类的组织与关系
1. 命名空间(Namespaces)
当项目变大,类的数量增多,可能会出现命名冲突。命名空间就像姓氏一样,用于组织和区分同名的类。
csharp
namespace MyCarFactory.Luxury
{
public class Car { /* ... */ }
}
namespace MyCarFactory.Utility
{
public class Car { /* ... */ }
}
2. 继承(Inheritance)
一个类可以从另一个类派生,获得其所有非私有的成员。这是OOP的另一大支柱,我们在此简单提及。
csharp
// SportsCar 继承自 Car
public class SportsCar : Car
{
public void ActivateTurbo()
{
// ...
}
}
结语
点个赞,关注我获取更多实用 C# 技术干货!如果觉得有用,记得收藏本文