
想象一下,你有一个存钱罐。你可以往里面存钱,也可以取钱,但你不需要知道存钱罐内部是怎么计算余额的。这就是封装的核心思想!

封装就像是一个黑盒子:
在C#中,我们用访问修饰符来设置"权限级别":
class BankAccount
{
private decimal balance; // 只有这个类自己能看
protected DateTime createdDate; // 这个类和它的"孩子"能看
internal string bankCode; // 同一个项目里的都能看
public string OwnerName; // 谁都能看
}
简单理解:
private:我的私人日记,只有我能看protected:家庭相册,我和家人能看internal:公司内部文件,同事都能看public:公开公告,谁都能看让我们看一个实际的例子:
class Employee
{
// 私有字段 - 外部不能直接访问
privatedecimal _salary;
// 公共属性 - 外部可以通过这个来访问
publicstring Name { get; set; }
publicdecimal Salary
{
get { return _salary; } // 读取薪资
privateset // 只能在内部修改
{
if (value < 0)
thrownew Exception("薪资不能为负数!");
_salary = value;
}
}
publicint Age
{
get { return _age; }
set
{
if (value < 18 || value > 65)
thrownew Exception("年龄必须在18-65岁之间");
_age = value;
}
}
}
使用方式:
Employee emp = new Employee();
emp.Name = "张三"; // ✅ 可以设置
emp.Age = 25; // ✅ 可以设置
// emp.Salary = 5000; // ❌ 会报错!不能直接设置薪资
emp.RaiseSalary(1000); // ✅ 只能通过特定方法修改

继承就像"子承父业":
// 父类(基类)
classVehicle // 交通工具
{
publicstring Brand { get; set; }
public void Start()
{
Console.WriteLine("交通工具启动了");
}
}
// 子类(派生类)
classCar : Vehicle // 汽车继承自交通工具
{
publicint Doors { get; set; }
public void Honk()
{
Console.WriteLine("滴滴!");
}
}
Car myCar = new Car();
myCar.Brand = "丰田"; // 从父类继承的属性
myCar.Doors = 4; // 自己的属性
myCar.Start(); // 从父类继承的方法
myCar.Honk(); // 自己的方法
有时候,子类想要改变父类的方法:
class Vehicle
{
public virtual void Start() // virtual表示可以重写
{
Console.WriteLine("交通工具启动了");
}
}
classCar : Vehicle
{
public override void Start() // override表示重写
{
Console.WriteLine("汽车点火启动了!");
}
}
class Car : Vehicle
{
public override void Start()
{
base.Start(); // 先执行父类的Start方法
Console.WriteLine("检查油量..."); // 再执行自己的逻辑
}
}
多态的意思是"多种形态"。就像"开车"这个动作:

方式一:虚方法重写
class Shape
{
public virtual void Draw() // 虚方法
{
Console.WriteLine("绘制形状");
}
}
classCircle : Shape
{
public override void Draw() // 重写方法
{
Console.WriteLine("绘制圆形");
}
}
classRectangle : Shape
{
public override void Draw() // 重写方法
{
Console.WriteLine("绘制矩形");
}
}
使用多态:
Shape[] shapes = new Shape[3];
shapes[0] = new Shape();
shapes[1] = new Circle();
shapes[2] = new Rectangle();
foreach (Shape shape in shapes)
{
shape.Draw(); // 同一个方法,不同表现!
}
输出结果:
绘制形状
绘制圆形
绘制矩形

抽象类就像建筑的设计图,但有些细节还没确定:
abstract classAnimal// 抽象类,不能直接创建对象
{
publicstring Name { get; set; }
// 抽象方法 - 只有定义,没有实现
public abstract void MakeSound();
// 普通方法 - 有具体实现
public void Sleep()
{
Console.WriteLine($"{Name}在睡觉");
}
}
classDog : Animal
{
// 必须实现抽象方法
public override void MakeSound()
{
Console.WriteLine("汪汪!");
}
}
使用:
// Animal animal = new Animal(); // ❌ 错误!不能创建抽象类对象
Animal myDog = new Dog(); // ✅ 正确!用子类创建
myDog.Name = "小白";
myDog.MakeSound(); // 输出:汪汪!
myDog.Sleep(); // 输出:小白在睡觉
接口定义了一个对象"能做什么",而不关心它"是什么":
// 定义接口
interfaceIFlyable
{
void Fly(); // 只有方法签名,没有实现
}
interfaceISwimmable
{
void Swim();
}
// 实现接口
classDuck : IFlyable, ISwimmable// 可以实现多个接口
{
public void Fly()
{
Console.WriteLine("鸭子在飞");
}
public void Swim()
{
Console.WriteLine("鸭子在游泳");
}
}
特性 | 抽象类 | 接口 |
|---|---|---|
定义 | "是什么"的关系 | "能做什么"的关系 |
方法 | 可以有具体方法 | 只有方法签名 |
继承 | 单继承 | 多实现 |
字段 | 可以有字段 | 不能有字段 |
使用场景 | 有共同基础的类 | 需要特定能力的类 |
❌ "我要用最复杂的技术" ✅ "用最适合当前需求的技术"
❌ "死记硬背语法" ✅ "理解设计思想和应用场景"
记住:面向对象编程是为了让代码更好理解、更好维护。选择合适的技术,而不是最复杂的技术!
掌握了这些基础概念后,你可以:
编程就像搭积木,先理解每个积木块的用途,再学习如何组合它们构建复杂系统!
.NET知识库,涵盖了.NET Web开发、桌面开发、微服务等视频教程,必读书籍推荐,教程源码,面试题库等全面学习资料