首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 物件導向設計實戰:從零打造「人-師-生」類別架構完整教學

     編輯:程式設計綜合問答

前言:為什麼需要良好的類別設計?

在 C# 開發中,合理的類別繼承體系是構建可維護、可擴展軟體的基石。本文將透過一個經典的「人員管理系統」案例,完整示範如何從需求分析出發,設計包含抽象基類、列舉、結構體、泛型集合與多型機制的完整類別架構。無論你是初學者還是想複習 OOP 核心觀念,這篇實戰教學都能幫你釐清關鍵細節。

一、 定義核心列舉型別

先建立系統所需的固定選項,使用 enum 強型別約束,避免魔術字串:

// 性別列舉
public enum SexType { 男, 女, 未知 }

// 教師職稱列舉
public enum ProTitle { 助教, 講師, 副教授, 教授, 未知 }

// 學生職務列舉
public enum StuTitle { 班長, 副班長, 學委, 學員 }

二、 抽象基類 Person:奠定共通契約

Person 類別定義所有共通屬性與抽象行為,強制衍生類實作特定邏輯:

  • 欄位:姓名、身高、體重、性別
  • 屬性:身分證字號(固定 18 碼驗證)、年齡(唯讀)
  • 方法:Saying() 抽象方法、序列化 Write/Read
  • 建構子:預設值初始化與參數化初始化雙軌並行
public abstract class Person
{
    // 私有欄位
    private string _name;
    private float _height;
    private float _weight;
    private SexType _sex;
    private string _id = "999999999999999999"; // 預設身分證

    // 屬性:身分證驗證邏輯
    public string ID
    {
        get => _id;
        set
        {
            if (System.Text.RegularExpressions.Regex.IsMatch(value, @"^\d{18}$"))
                _id = value;
        }
    }

    // 唯讀年齡屬性(實際專案中應由出生日期計算)
    public int Age { get; private set; }

    // 建構子
    public Person() { } // 使用預設值

    public Person(string name, string id, float height, float weight, SexType sex)
    {
        _name = name; ID = id; _height = height; _weight = weight; _sex = sex;
    }

    // 抽象方法:強制子類實作
    public abstract void Saying();
    public abstract void Write(System.IO.FileStream fs);
    public abstract void Read(System.IO.FileStream fs);
}

三、 Teacher 類別:繼承與集合管理

教師類別展示如何管理「課程清單」並防止重複:

public class Teacher : Person
{
    public ProTitle Title { get; set; }
    private List<string> _courses = new List<string>();

    // 唯讀屬性:課程數量
    public int CourseNumber => _courses.Count;

    // 新增課程(不可重複)
    public string CourseAdd(string courseName)
    {
        if (_courses.Contains(courseName)) return "課程已存在";
        _courses.Add(courseName);
        return "新增成功";
    }

    // 刪除課程
    public string CourseDelete(string courseName)
    {
        if (!_courses.Remove(courseName)) return "課程不存在";
        return "刪除成功";
    }

    // 覆寫抽象方法
    public override void Saying() => Console.WriteLine("我正在講課,不方便接電話");

    // 覆寫 ToString 整合資訊
    public override string ToString() => $"教師:{_name},職稱:{Title},課程數:{CourseNumber}";

    // 序列化方法留待實作
    public override void Write(System.IO.FileStream fs) { /* 實作邏輯 */ }
    public override void Read(System.IO.FileStream fs) { /* 實作邏輯 */ }
}

四、 結構體與 Student 類別:值型別與效能考量

課程成績採用 struct 節省記憶體,學生類別示範方法多載與統計運算:

// 結構體:輕量級資料容器
public struct CourseScore
{
    public string CourseName;
    public float Score;
}

public class Student : Person
{
    public string StuID { get; set; }
    public StuTitle Title { get; set; }
    private List<CourseScore> _scores = new List<CourseScore>();

    public int CourseNumber => _scores.Count;

    // 方法多載:兩種新增方式
    public void CourseAdd(string courseName, float score)
        => _scores.Add(new CourseScore { CourseName = courseName, Score = score });

    public void CourseAdd(CourseScore course) => _scores.Add(course);

    // 覆寫行為
    public override void Saying() => Console.WriteLine("我正在上課,不方便接電話");

    // 統計方法:使用 ref 回傳多值
    public void GetScore(ref double high, ref double low, ref double avg)
    {
        if (_scores.Count == 0) { high = low = avg = 0; return; }
        high = _scores.Max(s => s.Score);
        low = _scores.Min(s => s.Score);
        avg = _scores.Average(s => s.Score);
    }

    public override string ToString()
        => $"學生:{_name},學號:{StuID},身分:{Title},平均:{_scores.Average(s => s.Score):F1}";

    public override void Write(System.IO.FileStream fs) { /* 實作 */ }
    public override void Read(System.IO.FileStream fs) { /* 實作 */ }
}

五、 關鍵設計重點總結

  1. 抽象基類定義契約,確保衍生類一致性
  2. 列舉型別替代字串常數,提供編譯期檢查
  3. 封裝集合配合唯讀屬性保護資料完整性
  4. 方法多載提供靈活的呼叫介面
  5. 結構體 vs 類別:小型、不可變資料優先考慮 struct
  6. 序列化介面預留擴充點,支援多種儲存策略

結語

這個完整範例涵蓋了 C# 物件導向的核心精華:封裝、繼承、多型與抽象。實務上可依需求擴充介面、加入資料驗證屬性或採用 Entity Framework 等 ORM 框架持久化。建議動手重寫一次,體會每個設計決策的權衡取捨。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved