首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >第五章:你的C#编程之旅:解密面向对象编程的“三把钥匙”

第五章:你的C#编程之旅:解密面向对象编程的“三把钥匙”

作者头像
云中小生
发布2025-11-26 13:22:13
发布2025-11-26 13:22:13
270
举报

C# 面向对象编程三大特性详解

  1. 封装是基础
  2. 继承建立层次
  3. 多态实现灵活

5.1 封装(Encapsulation)

什么是封装?

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

封装就像是一个黑盒子:

  • 外面的人只能通过指定的"开口"(公共方法)来使用
  • 内部的复杂机制被隐藏起来
  • 使用起来更简单,也更安全

为什么要使用封装?

  1. 安全性:防止数据被意外修改
  2. 易用性:使用者不需要了解内部细节
  3. 可维护性:内部修改不影响外部使用

访问修饰符:控制谁能看到什么

在C#中,我们用访问修饰符来设置"权限级别":

代码语言:javascript
复制
class BankAccount
{
    private decimal balance;        // 只有这个类自己能看
    protected DateTime createdDate; // 这个类和它的"孩子"能看  
    internal string bankCode;       // 同一个项目里的都能看
    public string OwnerName;        // 谁都能看
}

简单理解:

  • private:我的私人日记,只有我能看
  • protected:家庭相册,我和家人能看
  • internal:公司内部文件,同事都能看
  • public:公开公告,谁都能看

实际应用:员工管理系统

让我们看一个实际的例子:

代码语言:javascript
复制
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;
        }
    }
}

使用方式:

代码语言:javascript
复制
Employee emp = new Employee();
emp.Name = "张三";        // ✅ 可以设置
emp.Age = 25;            // ✅ 可以设置
// emp.Salary = 5000;     // ❌ 会报错!不能直接设置薪资
emp.RaiseSalary(1000);   // ✅ 只能通过特定方法修改

封装的好处总结

  1. 数据验证:确保数据符合业务规则
  2. 安全性:防止不合理的数据修改
  3. 灵活性:可以随时修改内部实现而不影响外部

5.2 继承(Inheritance)

什么是继承?

继承就像"子承父业":

  • 儿子会继承父亲的特征和能力
  • 但儿子也可以有自己的特色
  • 这样可以避免重复造轮子

基本语法

代码语言:javascript
复制
// 父类(基类)
classVehicle           // 交通工具
{
    publicstring Brand { get; set; }
    public void Start()
    {
        Console.WriteLine("交通工具启动了");
    }
}

// 子类(派生类)
classCar : Vehicle     // 汽车继承自交通工具
{
    publicint Doors { get; set; }
    
    public void Honk()
    {
        Console.WriteLine("滴滴!");
    }
}

继承的使用

代码语言:javascript
复制
Car myCar = new Car();
myCar.Brand = "丰田";   // 从父类继承的属性
myCar.Doors = 4;        // 自己的属性
myCar.Start();          // 从父类继承的方法
myCar.Honk();           // 自己的方法

方法重写:青出于蓝

有时候,子类想要改变父类的方法:

代码语言:javascript
复制
class Vehicle
{
    public virtual void Start()  // virtual表示可以重写
    {
        Console.WriteLine("交通工具启动了");
    }
}

classCar : Vehicle
{
    public override void Start() // override表示重写
    {
        Console.WriteLine("汽车点火启动了!");
    }
}

base关键字:引用父类

代码语言:javascript
复制
class Car : Vehicle
{
    public override void Start()
    {
        base.Start();  // 先执行父类的Start方法
        Console.WriteLine("检查油量..."); // 再执行自己的逻辑
    }
}

继承的注意事项

  1. 单一继承:一个类只能有一个父类
  2. 传递性:继承关系会传递(爷爷→爸爸→儿子)
  3. 构造顺序:先构造父类,再构造子类

5.3 多态(Polymorphism)

什么是多态?

多态的意思是"多种形态"。就像"开车"这个动作:

  • 开轿车、开卡车、开公交车都是"开车"
  • 但具体怎么开,每种车都不一样

多态的实现方式

方式一:虚方法重写

代码语言:javascript
复制
class Shape
{
    public virtual void Draw()  // 虚方法
    {
        Console.WriteLine("绘制形状");
    }
}

classCircle : Shape
{
    public override void Draw() // 重写方法
    {
        Console.WriteLine("绘制圆形");
    }
}

classRectangle : Shape
{
    public override void Draw() // 重写方法
    {
        Console.WriteLine("绘制矩形");
    }
}

使用多态:

代码语言:javascript
复制
Shape[] shapes = new Shape[3];
shapes[0] = new Shape();
shapes[1] = new Circle();
shapes[2] = new Rectangle();

foreach (Shape shape in shapes)
{
    shape.Draw();  // 同一个方法,不同表现!
}

输出结果:

代码语言:javascript
复制
绘制形状
绘制圆形  
绘制矩形

多态的优势

  1. 代码通用性:用统一的接口处理不同类型的对象
  2. 扩展性好:添加新类型时不需要修改现有代码
  3. 可替换性:不同对象可以相互替换

5.4 抽象类与接口

抽象类:不完全的蓝图

抽象类就像建筑的设计图,但有些细节还没确定:

代码语言:javascript
复制
abstract classAnimal// 抽象类,不能直接创建对象
{
    publicstring Name { get; set; }
    
    // 抽象方法 - 只有定义,没有实现
    public abstract void MakeSound();
    
    // 普通方法 - 有具体实现
    public void Sleep()
    {
        Console.WriteLine($"{Name}在睡觉");
    }
}

classDog : Animal
{
    // 必须实现抽象方法
    public override void MakeSound()
    {
        Console.WriteLine("汪汪!");
    }
}

使用:

代码语言:javascript
复制
// Animal animal = new Animal();  // ❌ 错误!不能创建抽象类对象
Animal myDog = new Dog();         // ✅ 正确!用子类创建
myDog.Name = "小白";
myDog.MakeSound();  // 输出:汪汪!
myDog.Sleep();      // 输出:小白在睡觉

接口:能力约定

接口定义了一个对象"能做什么",而不关心它"是什么":

代码语言:javascript
复制
// 定义接口
interfaceIFlyable
{
    void Fly();  // 只有方法签名,没有实现
}

interfaceISwimmable
{
    void Swim();
}

// 实现接口
classDuck : IFlyable, ISwimmable// 可以实现多个接口
{
    public void Fly()
    {
        Console.WriteLine("鸭子在飞");
    }
    
    public void Swim()
    {
        Console.WriteLine("鸭子在游泳");
    }
}

抽象类 vs 接口

特性

抽象类

接口

定义

"是什么"的关系

"能做什么"的关系

方法

可以有具体方法

只有方法签名

继承

单继承

多实现

字段

可以有字段

不能有字段

使用场景

有共同基础的类

需要特定能力的类

实际选择建议

  • 抽象类:当多个类有共同的基类和共享代码时
  • 接口:当需要定义一组相关功能,或者需要多继承时

💡 学习建议

理解概念比记忆语法更重要

  1. 封装:想着"存钱罐",隐藏细节,提供接口
  2. 继承:想着"父子关系",代码复用,层次结构
  3. 多态:想着"同一操作,不同表现",提高灵活性

循序渐进的学习路径

  1. 先掌握封装 - 这是基础
  2. 再学习继承 - 理解代码复用
  3. 然后学习多态 - 提高设计能力
  4. 最后区分抽象类和接口 - 完成进阶

常见误区避免

❌ "我要用最复杂的技术" ✅ "用最适合当前需求的技术"

❌ "死记硬背语法" ✅ "理解设计思想和应用场景"

记住:面向对象编程是为了让代码更好理解、更好维护。选择合适的技术,而不是最复杂的技术!


🎯 下一步学习

掌握了这些基础概念后,你可以:

  1. 尝试设计一个小型项目
  2. 练习识别什么时候该用继承、什么时候该用接口
  3. 学习设计模式,了解这些特性的实际应用

编程就像搭积木,先理解每个积木块的用途,再学习如何组合它们构建复杂系统!

附录

.NET知识库,涵盖了.NET Web开发、桌面开发、微服务等视频教程,必读书籍推荐,教程源码,面试题库等全面学习资料

  • 知识库链接:https://pan.quark.cn/s/1dd8efd19cf3
  • 备用链接:https://pan.xunlei.com/s/VOeq4zwEgSRv1GOvDOzIGgTlA1?pwd=yarh#
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 .NET修仙日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C# 面向对象编程三大特性详解
    • 5.1 封装(Encapsulation)
      • 什么是封装?
      • 为什么要使用封装?
      • 访问修饰符:控制谁能看到什么
      • 实际应用:员工管理系统
      • 封装的好处总结
    • 5.2 继承(Inheritance)
      • 什么是继承?
      • 基本语法
      • 继承的使用
      • 方法重写:青出于蓝
      • base关键字:引用父类
      • 继承的注意事项
    • 5.3 多态(Polymorphism)
      • 什么是多态?
      • 多态的实现方式
      • 多态的优势
    • 5.4 抽象类与接口
      • 抽象类:不完全的蓝图
      • 接口:能力约定
      • 抽象类 vs 接口
      • 实际选择建议
    • 💡 学习建议
      • 理解概念比记忆语法更重要
      • 循序渐进的学习路径
      • 常见误区避免
    • 🎯 下一步学习
    • 附录
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档