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

C# 類別設計作業解析:Person-Teacher-Student 三層架構完整實作

     編輯:程式設計綜合問答

案例背景

這是一個典型的 C# 物件導向程式設計作業,要求建立包含抽象基類、繼承關係、列舉約束、集合管理與序列化介面的完整類別體系。本文將需求拆解為可執行的程式碼模組,並說明關鍵設計決策。

核心類別結構圖

Person (abstract)
├── Fields: Name, Height, Weight, Sex
├── Properties: ID (18碼驗證), Age (readonly)
├── Methods: Saying(), Write(), Read()
├── Constructors: default / parameterized
│
├── Teacher : Person
│   ├── Fields: Title(ProTitle), Courses(List<string>)
│   ├── Property: CourseNumber (readonly)
│   ├── Methods: CourseAdd(), CourseDelete()
│   └── Overrides: Saying(), ToString(), Write(), Read()
│
└── Student : Person
    ├── Fields: StuID, CourseScore(List<CourseScore>), Title(StuTitle)
    ├── Property: CourseNumber (readonly)
    ├── Methods: CourseAdd() overloads, GetScore(ref high, low, avg)
    └── Overrides: Saying(), ToString(), Write(), Read()

關鍵程式碼片段

1. 抽象基類 Person 完整實作

public abstract class Person
{
    protected string Name;
    protected float Height, Weight;
    protected SexType Sex;
    private string _id = "999999999999999999";

    public string ID
    {
        get => _id;
        set { if (Regex.IsMatch(value, @"^\d{18}$")) _id = value; }
    }

    public int Age { get; protected set; }

    public Person() { }
    public Person(string name, string id, float h, float w, SexType s)
    { Name = name; ID = id; Height = h; Weight = w; Sex = s; }

    public abstract void Saying();
    public abstract void Write(FileStream fs);
    public abstract void Read(FileStream fs);
}

2. Teacher 類別:私有集合封裝與業務邏輯

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

    public int CourseNumber => _courses.Count;

    public string CourseAdd(string name)
    {
        if (_courses.Contains(name)) return "課程重複";
        _courses.Add(name);
        return "成功";
    }

    public string CourseDelete(string name)
        => _courses.Remove(name) ? "成功" : "找不到課程";

    public override void Saying() => Console.WriteLine("我正在講課,不方便接電話");
    public override string ToString() => $"[教師]{Name} {Title} 授課數:{CourseNumber}";
    public override void Write(FileStream fs) { /* TODO */ }
    public override void Read(FileStream fs) { /* TODO */ }
}

3. 結構體與 Student 統計功能

public struct CourseScore { public string CourseName; public float Score; }

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

    public int CourseNumber => _scores.Count;

    public void CourseAdd(string name, float score)
        => _scores.Add(new CourseScore { CourseName = name, Score = score });
    public void CourseAdd(CourseScore cs) => _scores.Add(cs);

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

    public void GetScore(ref double high, ref double low, ref double avg)
    {
        if (_scores.Count == 0) { high = low = avg = 0; return; }
        high = _scores.Max(x => x.Score);
        low = _scores.Min(x => x.Score);
        avg = _scores.Average(x => x.Score);
    }

    public override string ToString()
        => $"[學生]{Name} {StuID} {Title} 科目數:{CourseNumber} 平均:{_scores.Average(x => x.Score):F1}";
    public override void Write(FileStream fs) { /* TODO */ }
    public override void Read(FileStream fs) { /* TODO */ }
}

常見錯誤與最佳實務

  • 忘記密封集合:公開 `List` 會導致外部任意修改,務必用 `private readonly` + 唯讀屬性
  • 身分證驗證缺失:應在 `set` 存取子中加入 `Regex` 驗證,而非事後檢查
  • 抽象方法未實作:衍生類必須 `override` 所有 `abstract` 成員,否則仍為抽象類別
  • 結構體可變性:`struct` 應設計為不可變,避免拷貝時的副作用

擴充建議

  1. 引入 `ISerializable` 或 JSON.NET 取代手動 `FileStream` 序列化
  2. 使用 `IReadOnlyList` 暴露集合,進一步防禦性程式設計
  3. 加入 `INotifyPropertyChanged` 支援 WPF/UWP 資料繫結
  4. 單元測試覆蓋 `CourseAdd` 重複檢查、`GetScore` 邊界條件
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved