第四章:C# 面向对象编程详解:从类与对象到完整项目实践

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 附录

教程源码已上传网盘,需要请自取

相关推荐
m0_738120722 小时前
内网横向靶场——记录一次横向渗透(三)
开发语言·网络·安全·web安全·网络安全·php
songroom2 小时前
Rust: 量化策略回测与简易线程池构建、子线程执行观测
开发语言·后端·rust
jz_ddk2 小时前
[数学基础] 瑞利分布:数学原理、物理意义及Python实验
开发语言·python·数学·概率论·信号分析
大G的笔记本2 小时前
Java JVM 篇常见面试题
java·开发语言·jvm
ZHE|张恒2 小时前
深入理解 Java 双亲委派机制:JVM 类加载体系全解析
java·开发语言·jvm
范德萨_2 小时前
JavaScript 实用技巧(总结)
开发语言·前端·javascript
1024小神2 小时前
Kotlin实现全屏显示效果,挖空和刘海屏适配
android·开发语言·kotlin
玖笙&3 小时前
✨WPF编程进阶【7.1】动画基础
c++·c#·wpf·visual studio