一、前言为什么需要体系化学习 C# 面向对象C# 作为 .NET 生态的核心语言其面向对象编程OOP特性不仅是语法基础更是构建可维护、可扩展软件系统的设计哲学。许多开发者虽然能写出 C# 代码但对类与对象、继承、多态、封装、抽象等核心概念的理解往往停留在“会用”层面缺乏体系化的认知框架。本文旨在为你提供一份从基础到进阶的 C# 面向对象通关指南通过清晰的脉络梳理和实战代码示例帮助你建立完整的知识体系真正掌握面向对象编程的精髓。二、面向对象编程四大支柱在深入具体语法前我们先从概念层面理解面向对象编程的四大支柱封装Encapsulation将数据字段和操作数据的方法方法捆绑在一起并对外隐藏内部实现细节仅通过公开的接口进行交互。继承Inheritance允许创建新类派生类基于现有类基类的属性和行为实现代码复用和层次化设计。多态Polymorphism同一操作作用于不同的对象可以有不同的解释和执行结果。主要通过方法重写和接口实现。抽象Abstraction隐藏复杂的实现细节仅向外界暴露必要的、简化的接口。三、类与对象面向对象的基石3.1 类的定义与实例化// 定义一个简单的 Person 类 public class Person { // 字段通常私有通过属性暴露 private string _name; private int _age; // 属性封装字段的访问 public string Name { get { return _name; } set { _name value; } } public int Age { get { return _age; } set { if (value 0) // 封装验证逻辑 _age value; else throw new ArgumentException(年龄不能为负数); } } // 构造函数 public Person(string name, int age) { Name name; Age age; } // 方法 public void Introduce() { Console.WriteLine($你好我是{Name}今年{Age}岁。); } } // 实例化对象 class Program { static void Main(string[] args) { Person person1 new Person(张三, 25); person1.Introduce(); // 输出你好我是张三今年25岁。 } }3.2 访问修饰符public完全公开任何地方都可访问。private仅类内部可访问默认。protected类内部和派生类可访问。internal同一程序集内可访问。protected internal同一程序集或派生类可访问。四、封装数据隐藏与安全访问封装不仅仅是使用private字段更重要的是通过属性、方法提供受控的访问通道。public class BankAccount { // 私有字段外部无法直接访问 private decimal _balance; private string _accountNumber; // 只读属性 public string AccountNumber _accountNumber; // 带逻辑的属性 public decimal Balance { get { return _balance; } private set // 存款操作在类内部完成 { if (value 0) _balance value; } } public BankAccount(string accountNumber, decimal initialBalance) { _accountNumber accountNumber; Balance initialBalance; } // 公开的存款方法 public void Deposit(decimal amount) { if (amount 0) throw new ArgumentException(存款金额必须大于0); Balance amount; Console.WriteLine($成功存入 {amount:C}当前余额{Balance:C}); } // 公开的取款方法带验证 public bool Withdraw(decimal amount) { if (amount 0) throw new ArgumentException(取款金额必须大于0); if (amount Balance) { Console.WriteLine(余额不足); return false; } Balance - amount; Console.WriteLine($成功取出 {amount:C}当前余额{Balance:C}); return true; } }五、继承代码复用与层次化设计5.1 基本继承语法// 基类父类 public class Vehicle { public string Brand { get; set; } public int Speed { get; protected set; } public Vehicle(string brand) { Brand brand; Speed 0; } public virtual void Accelerate(int increment) { Speed increment; Console.WriteLine(${Brand} 加速到 {Speed} km/h); } public void Brake() { Speed 0; Console.WriteLine(${Brand} 已刹车); } } // 派生类子类 public class Car : Vehicle { public int DoorCount { get; set; } public Car(string brand, int doorCount) : base(brand) { DoorCount doorCount; } // 重写基类方法 public override void Accelerate(int increment) { // 调用基类实现 base.Accelerate(increment); Console.WriteLine($这是一辆{DoorCount}门轿车); } // 子类特有方法 public void Honk() { Console.WriteLine(${Brand} 鸣笛嘀嘀); } } // 使用 class Program { static void Main(string[] args) { Car myCar new Car(Toyota, 4); myCar.Accelerate(50); // 输出Toyota 加速到 50 km/h这是一辆4门轿车 myCar.Honk(); // 输出Toyota 鸣笛嘀嘀 } }5.2 继承中的构造函数调用顺序派生类构造函数首先调用基类构造函数通过: base(...)执行基类构造函数体通过: sohuedu.cN(...)执行派生类构造函数体5.3sealed关键字使用sealed修饰类可以防止该类被继承public sealed class FinalClass { // 这个类不能被继承 } // 错误无法从密封类派生 // public class DerivedClass : FinalClass { }六、多态同一接口不同实现6.1 方法重写override与虚方法virtualpublic class Shape { public virtual void Draw() { Console.WriteLine(绘制一个形状); } } public class Circle : Shape { public override void Draw() { Console.WriteLine(绘制一个圆形); } } public class Rectangle : Shape { public override void Draw() { Console.WriteLine(绘制一个矩形); } } class Program { static void Main(string[] args) { // 多态父类引用指向子类对象 Shape shape1 new Circle(); Shape shape2 new Rectangle(); Shape shape3 new Shape(); shape1.Draw(); // 输出绘制一个圆形 shape2.Draw(); // 输出绘制一个矩形 shape3.Draw(); // 输出绘制一个形状 } }6.2 抽象类与抽象方法// 抽象类不能实例化只能被继承 public abstract class Animal { // 抽象方法没有实现必须在派生类中重写 public abstract void MakeSound(); // 普通方法可以有实现 public void Sleep() { Console.WriteLine(动物正在睡觉...); } } public class Dog : Animal { public override void MakeSound() { Console.WriteLine(汪汪); } } public class Cat : Animal { public override void MakeSound() { Console.WriteLine(喵喵); } } class Program { static void Main(string[] args) { Animal dog new Dog(); Animal cat new Cat(); dog.MakeSound(); // 汪汪 cat.MakeSound(); // 喵喵 // 错误无法创建抽象类的实例 // Animal animal new Animal(); } }七、接口契约式编程7.1 接口定义与实现// 接口定义只包含方法、属性、事件、索引器的签名 public interface ILogger { void Log(string message); void LogError(string error); } public interface IConfigurable { string Configuration { get; set; } } // 类可以实现多个接口 public class FileLogger : ILogger, IConfigurable { public string Configuration { get; set; } public void Log(string message) { Console.WriteLine($[INFO] {DateTime.Now}: {message}); } public void LogError(string error) { Console.WriteLine($[ERROR] {DateTime.Now}: {error}); } } public class DatabaseLogger : ILogger { public void Log(string message) { // 模拟写入数据库 Console.WriteLine($写入数据库日志: {message}); } public void LogError(string error) { Console.WriteLine($写入数据库错误: {error}); } } class Program { static void Main(string[] args) { ILogger logger new FileLogger(); logger.Log(应用程序启动); logger new DatabaseLogger(); logger.LogError(数据库连接失败); } }7.2 接口 vs 抽象类特性接口抽象类多重继承支持一个类可实现多个接口不支持一个类只能继承一个抽象类默认实现C# 8.0 前不支持8.0 后支持默认方法支持字段不能包含aupuyb.cN实例字段可以包含字段构造函数不能有构造函数可以有构造函数访问修饰符成员默认 public可以有各种访问修饰符设计目的定义契约/能力提供通用基类实现八、进阶特性8.1 属性与自动属性// 完整属性带私有字段 private string _name; public string Name { get { return _name; } set { _name value; } } // 自动属性编译器自动生成私有字段 public string Name { get; set; } // 只读自动属性只能在构造函数中赋值 public string Id { get; } // 表达式体属性C# 6.0 public string FullName ${FirstName} {LastName}; // 属性初始化器C# 6.0 public Liststring Tags { get; set; } new Liststring();8.2 静态类与静态成员// 静态类不能实例化只能包含静态成员 public static class MathHelper { public static double PI 3.1415926; public static int Add(int a, int b) a b; public static int Max(int a, int b) a b ? a : b; } // 使用静态类 double area MathHelper.PI * radius * radius; int sum MathHelper.Add(10, 20); // 静态构造函数在类首次使用前自动调用一次 public class Configuration { public static string ConnectionString { get; } static Configuration() { ConnectionString Serverlocalhost;DatabaseTest;; Console.WriteLine(静态构造函数被调用); } }8.3 索引器public class StringCollection { private Liststring _items new Liststring(); // 索引器使对象可以像数组一样使用 public string this[int index] { get _items[index]; set _items[index] value; } public void Add(string item) _items.Add(item); public int Count _items.Count; } class Program { static void Main(string[] args) { var collection new StringCollection(); collection.Add(第一项); collection.Add(第二项); // 使用索引器访问 Console.WriteLine(collection[0]); // 输出第一项 collection[1] 修改后的第二项; } }九、设计原则与最佳实践9.1 SOLID 原则在 C# 中的体现单一职责原则SRP一个类只负责一件事开闭原则OCP对扩展开放对修改关闭使用抽象和接口里氏替换原则LSP派生类必须能够替换其基类接口隔离原则ISP多个特定接口优于一个通用接口依赖倒置原则DIP依赖抽象不依赖具体实现9.2 常见设计模式示例// 工厂模式示例 public interface IShape { void Draw(); } public class Circle : IShape { public void Draw() Console.WriteLine(绘制圆形); } public class Rectangle : IShape { public void Draw() Console.WriteLine(绘制矩形); } public static class ShapeFactory { public static IShape CreateShape(string shapeType) { return shapeType.ToLower() switch { circle new Circle(), rectangle new Rectangle(), _ throw new ArgumentException(不支持的形状类型) }; } } // 策略模式示例 public interface IPaymentStrategy { void Pay(decimal amount); } public class CreditCardPayment : IPaymentStrategy { public void Pay(decimal amount) Console.WriteLine($信用卡支付 {amount:C}); } public class PayPalPayment : IPaymentStrategy { public void Pay(decimal amount) Console.WriteLine($PayPal 支付 {amount:C}); } public class ShoppingCart { private IPaymentStrategy _paymentStrategy; public void SetPaymentStrategy(IPaymentStrategy strategy) { _paymentStrategy strategy; } public void Checkout(decimal amount) { _paymentStrategy?.Pay(amount); } }十、实战构建一个简单的电商系统模型// 抽象产品类 public abstract class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public abstract string GetDescription(); public virtual decimal CalculateDiscount(int quantity) { return quantity 10 ? Price * 0.1m : 0; } } // 具体产品类 public class Book : Product { public string Author { get; set; } public string ISBN { get; set; } public override string GetDescription() { return ${Name} by {Author} (ISBN: {ISBN}); } public override decimal CalculateDiscount(int quantity) { // 书籍的特殊折扣规则 var baseDiscount base.CalculateDiscount(quantity); return baseDiscount (quantity 5 ? Price * 0.05m : 0); } } public class Electronics : Product { public string Brand { get; set; } public string Model { get; set; } public override string GetDescription() { return ${Brand} {Model} - {Name}; } } // 接口可发货 public interface IShippable { decimal CalculateShippingCost(string destination); void MarkAsShipped(); } // 订单类 public class Order { private ListProduct _products new ListProduct(); public void AddProduct(Product product) _products.Add(product); public decimal CalculateTotal() { return _products.Sum(p