C# 面向对象编程详解:从类与对象到完整项目实践
4.1 类(Class)与对象(Object)的概念
核心概念解析
类(Class) 是面向对象编程的蓝图或模板,它定义了:
-
数据成员:字段和属性,用于存储对象状态
-
行为成员:方法,定义对象能执行的操作
-
构造机制:构造函数,用于创建和初始化对象
对象(Object) 是类的具体实例,是根据类定义创建的现实实体。

类与对象关系流程图
现实世界类比
// 类:就像汽车的设计图纸
class Car
{
// 属性:颜色、品牌、速度等
public string Color { get; set; }
public string Brand { get; set; }
// 方法:启动、加速、刹车等
public void Start() { /* 启动逻辑 */ }
public void Accelerate() { /* 加速逻辑 */ }
}
// 对象:就像根据图纸制造的具体汽车
Car myCar = new Car(); // 我的汽车
Car yourCar = new Car(); // 你的汽车
第一个完整的类示例
using System;
// 定义一个Person类
class Person
{
// 字段 - 存储数据
public string name;
public int age;
// 方法 - 定义行为
public void Introduce()
{
Console.WriteLine($"你好,我叫{name},今年{age}岁。");
}
}
class Program
{
static void Main()
{
// 创建Person类的对象(实例化)
Person person1 = new Person();
person1.name = "张三";
person1.age = 25;
person1.Introduce(); // 输出:你好,我叫张三,今年25岁。
Person person2 = new Person();
person2.name = "李四";
person2.age = 30;
person2.Introduce(); // 输出:你好,我叫李四,今年30岁。
}
}
4.2 字段(Field)与属性(Property)
字段(Field)
字段是直接在类中声明的变量,用于存储对象的状态数据。
class Student
{
// 公共字段 - 通常使用小写字母开头
public string name;
public int age;
// 私有字段 - 只能在类内部访问
private double gpa;
// 静态字段 - 属于类本身,所有实例共享
private static int studentCount = 0;
}
属性(Property)
属性提供了对字段的安全访问机制,可以添加验证逻辑。

属性访问流程图
完整属性(Full Property)
class BankAccount
{
private double balance; // 私有字段
// 属性 - 提供对balance字段的受控访问
public double Balance
{
get { return balance; } // 读取值
set
{
// 添加验证逻辑
if (value >= 0)
balance = value;
else
Console.WriteLine("余额不能为负数!");
}
}
private string accountNumber;
// 只读属性
public string AccountNumber
{
get { return accountNumber; }
}
}
自动属性(Auto Property)
当不需要额外逻辑时,可以使用简洁的自动属性:
class Product
{
// 自动属性 - 编译器自动生成私有字段
public string Name { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
// 只读自动属性(只能在构造函数中设置)
public string Category { get; }
// 带有不同访问级别的属性
public string InternalCode { get; private set; }
}
字段与属性的使用场景对比
class Employee
{
// 字段 - 用于内部计算,不需要外部访问
private DateTime hireDate;
private int workingYears;
// 属性 - 需要验证或计算的公共数据
private string _name;
public string Name
{
get { return _name; }
set
{
if (!string.IsNullOrWhiteSpace(value))
_name = value.Trim();
else
throw new ArgumentException("姓名不能为空");
}
}
// 计算属性(只有getter)
public bool IsEligibleForPromotion
{
get { return workingYears >= 3; }
}
// 自动属性
public string Department { get; set; }
}
4.3 方法(Method)
方法的基本定义
方法是类中定义行为的方式,包含执行特定任务的语句块。
class Calculator
{
// 无参数无返回值的方法
public void ShowWelcome()
{
Console.WriteLine("欢迎使用计算器!");
}
// 有参数无返回值的方法
public void PrintMessage(string message)
{
Console.WriteLine($"消息:{message}");
}
// 有参数有返回值的方法
public int Add(int a, int b)
{
return a + b;
}
// 多个参数的方法
public double CalculateBMI(double weight, double height)
{
return weight / (height * height);
}
}

方法调用执行流程图
方法重载(Overload)
同一个类中可以有多个同名方法,只要参数列表不同:
class MathOperations
{
// 整数相加
public int Add(int a, int b)
{
return a + b;
}
// 浮点数相加 - 参数类型不同
public double Add(double a, double b)
{
return a + b;
}
// 三个数相加 - 参数数量不同
public int Add(int a, int b, int c)
{
return a + b + c;
}
}

方法重载解析流程图
参数传递方式
class ParameterDemo
{
// 值传递 - 传递参数的副本
public void IncrementValue(int number)
{
number++;
Console.WriteLine($"方法内: {number}");
}
// 引用传递 - 使用ref关键字
public void IncrementRef(ref int number)
{
number++;
Console.WriteLine($"方法内: {number}");
}
// 输出参数 - 使用out关键字
public void GetUserInfo(out string name, out int age)
{
name = "张三"; // 必须赋值
age = 25; // 必须赋值
}
}
4.4 构造函数与析构函数
构造函数(Constructor)
构造函数在创建对象时自动调用,用于初始化对象。
class Book
{
public string Title { get; set; }
public string Author { get; set; }
public decimal Price { get; set; }
// 默认构造函数
public Book()
{
Title = "未知";
Author = "未知";
Price = 0;
}
// 参数化构造函数
public Book(string title, string author, decimal price)
{
Title = title;
Author = author;
Price = price;
}
// 构造函数重载
public Book(string title, string author) : this(title, author, 0)
{
// 使用this调用其他构造函数
}
}

对象生命周期流程图
静态构造函数
静态构造函数用于初始化类的静态成员。
class Configuration
{
public static string DatabaseConnection { get; private set; }
public static DateTime InitializeTime { get; private set; }
// 静态构造函数
static Configuration()
{
DatabaseConnection = "Server=localhost;Database=MyApp;";
InitializeTime = DateTime.Now;
}
}
析构函数
class ResourceManager
{
private string resourceName;
public ResourceManager(string name)
{
resourceName = name;
}
// 析构函数
~ResourceManager()
{
Console.WriteLine($"资源 '{resourceName}' 正在被清理");
// 释放非托管资源
}
}
注意 :在现代C#中,通常使用 IDisposable 接口而不是析构函数来管理资源。
4.5 📝 动手练习
练习1:银行账户类
class BankAccount
{
public string AccountNumber { get; }
public string Owner { get; set; }
public decimal Balance { get; private set; }
// 静态字段
private static int accountCount = 0;
public BankAccount(string owner, decimal initialBalance = 0)
{
AccountNumber = GenerateAccountNumber();
Owner = owner;
Balance = initialBalance;
accountCount++;
}
public void Deposit(decimal amount)
{
if (amount <= 0)
{
Console.WriteLine("存款金额必须大于0");
return;
}
Balance += amount;
Console.WriteLine($"成功存款 {amount:C},当前余额: {Balance:C}");
}
public void DisplayInfo()
{
Console.WriteLine("=== 账户信息 ===");
Console.WriteLine($"账号: {AccountNumber}");
Console.WriteLine($"户主: {Owner}");
Console.WriteLine($"余额: {Balance:C}");
}
private string GenerateAccountNumber()
{
return "ACC" + DateTime.Now.ToString("yyyyMMddHHmmss");
}
}

银行账户操作流程图
练习2:学生成绩管理系统学生类
class Student
{
public string StudentId { get; }
public string Name { get; set; }
private double[] grades;
// 计算属性
public double GPA
{
get
{
if (grades.Length == 0) return 0;
return grades.Average();
}
}
public Student(string studentId, string name)
{
StudentId = studentId;
Name = name;
grades = new double[0];
}
public void AddGrade(double grade)
{
Array.Resize(ref grades, grades.Length + 1);
grades[grades.Length - 1] = grade;
}
public void DisplayInfo()
{
Console.WriteLine($"学号: {StudentId}, 姓名: {Name}, 平均分: {GPA:F1}");
}
}

学生成绩管理流程图
练习3:游戏角色战斗系统游戏角色类
class GameCharacter
{
public string Name { get; }
public int Health { get; private set; }
public bool IsAlive => Health > 0;
public GameCharacter(string name)
{
Name = name;
Health = 100;
}
public void Attack(GameCharacter target)
{
if (!IsAlive || !target.IsAlive) return;
int damage = 20;
target.TakeDamage(damage);
Console.WriteLine($"{Name} 攻击了 {target.Name}");
}
public void TakeDamage(int damage)
{
Health -= damage;
if (Health < 0) Health = 0;
}
}

游戏战斗系统流程图
💡 重点回顾
-
类与对象:类是蓝图,对象是具体实例
-
封装性:使用访问修饰符控制成员可见性
-
字段与属性:字段存储数据,属性提供安全访问
-
方法重载:同名方法,不同参数列表
-
构造函数:初始化对象,支持重载
-
静态成员:属于类本身,所有实例共享

面向对象核心概念关系图
🎯 综合项目挑战:图书馆管理系统
创建一个完整的图书馆管理系统,包含以下功能:
核心类设计
Book类:
-
属性:ISBN、书名、作者、出版年份、是否借出
-
方法:借书、还书、显示信息
Member类:
-
属性:会员ID、姓名、借书列表
-
方法:借书、还书、显示借阅历史
Library类:
-
属性:图书列表、会员列表
-
方法:添加图书、搜索图书、统计信息

图书馆系统架构图
高级功能
-
使用静态成员跟踪总数
-
实现多条件图书搜索
-
添加借书限制(最多5本)
-
实现逾期罚款系统
图书借阅流程

图书借阅流程
通过这个完整的项目,你将全面掌握C#面向对象编程的核心概念和实践技能!
4.6 附录
教程源码已上传网盘,需要请自取