首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 核心編程:深入理解類與對象

     編輯:關於C語言

前言:組件編程與面向對象的關係

組件編程並非對傳統面向對象編程(OOP)的拋棄,而是其深化與發展。類作為面向對象的核心靈魂,在 C# 語言中擁有廣泛而深入的應用。許多極具「Sharp」特色的組件特性,實際上都是直接由類封裝而成。因此,深度掌握類的機制,是邁向 C# 專家之路的關鍵一環。

類的結構與成員

C# 的類是一種封裝數據成員、函數成員及嵌套類型的數據結構。其成員豐富多樣:

  • 數據成員:常量、域
  • 函數成員:方法、屬性、索引器、事件、運算符、實例構造函數、靜態構造函數、析構函數

除部分外部引入方法外,類及其成員的聲明與實現通常放在一起。關於構造函數、析構函數、域、方法、屬性與索引器的詳細剖析,將在後續章節展開。

類的訪問修飾符

C# 通過多種修飾符表達類的不同性質,根據保護級別分為五種:

  1. public:任意存取
  2. protected:僅限本類及繼承子類存取
  3. internal:僅限本組件內所有類存取。組件是 C# 中類組合後的邏輯與物理單位,編譯後通常為 .DLL 或 .EXE
  4. protected internal:唯一的組合修飾符,限本組件內所有類及其繼承子類存取
  5. private:僅限本類存取

非嵌套類(命名空間或編譯單元層級)僅能使用 public 和 internal 修飾。new 修飾符僅用於嵌套類,表示隱藏繼承自父類的同名類型。

抽象類與密封類

抽象類

使用 abstract 修飾的類只能作為父類被繼承,不能實例化。抽象類可包含抽象成員,但非強制。abstract 不能與 new 同時使用。示例:

abstract class A { public abstract void F(); }
abstract class B : A { public void G() {} }
class C : B { public override void F() { /* 實現 F */ } }

類 A 含抽象方法 F(),不可實例化。類 B 繼承 A 但未實現 F(),故仍為抽象類。類 C 實現 F() 後才能實例化。

密封類

sealed 修飾符禁止類被繼承。同時使用 abstract 和 sealed 無意義且被禁止。

對象與 this 關鍵字

類與對象的區別

類是成員的封裝設計,而對象實例化並在其數據成員上操作才是完成任務的根本。實例化語法:MyClass myObject = new MyClass(),new 會調用相應構造函數。C# 所有對象均創建在托管堆上。實例化後的類型稱為對象,核心特徵是擁有自己特有的數據成員拷貝,稱為實例成員。反之,不屬於特定對象的數據成員稱為靜態成員,用 static 聲明。靜態成員只能通過類名引用。

this 關鍵字詳解

this 引用當前對象實例的成員。在實例方法中可省略 this 直接引用成員,語義相同。靜態成員函數沒有 this 指針。this 主要用於:

  • 構造函數中限定被同名參數隱藏的成員
  • 將對象作為參數傳遞給其他方法
  • 聲明索引器時
// 構造函數中使用 this
class Employee {
    public Employee(string name, string alias) {
        this.name = name;
        this.alias = alias;
    }
}

// 作為參數傳遞
CalcTax(this);

// 索引器聲明
public int this[int param] {
    get { return array[param]; }
    set { array[param] = value; }
}

System.Object 類:所有類的根基

C# 所有類直接或間接繼承自 System.Object,實現單根繼承。若未指定基類,編譯器預設繼承 Object。Object 類也可用 object 關鍵字表示。掌握其公共接口對理解 C# 類行為至關重要。

核心方法解析

Equals 與 相等性判斷

面向對象中有兩個重要相等概念:

  • 值相等:數據成員按內存位分別相等
  • 引用相等:指向同一內存地址(對象句柄相等)。引用相等必然推導出值相等

Object.Equals(objA, objB) 靜態方法先檢查是否均為 null,否則調用 objA.Equals(objB)。實例方法 Equals(obj) 預設實現為引用相等判斷(return this == obj),但為虛方法,建議重寫以判斷值相等。.NET 框架中 String、Int32 等已重寫,但 Array 未重寫。值類型(繼承自 ValueType)均重寫了 Equals 判斷值相等。

注意:x.Equals(null) 返回 false(x 不能為 null)。若兩對象可能為 null,必須用靜態 Object.Equals。對於值類型,重寫 Equals 時應重載 == 運算符;引用類型一般不重載 ==,保持引用相等語義。

ReferenceEquals

靜態方法 ReferenceEquals(objA, objB) 判斷引用相等。引用類型下語義等同於未重載的 ==;值類型下必定返回 false。

GetHashCode

為類型提供哈希碼,用於哈希算法/表。重寫 Equals 時必須重寫 GetHashCode,確保值相等的對象哈希碼相等。

其他方法

  • GetType():查詢運行時類型,與 typeof 語義相同
  • ToString():返回對象字符串表示,未重寫時返回類型名
  • Finalize():受保護方法,與析構函數相關,後續章節詳述
  • MemberwiseClone():返回「淺拷貝」(按位拷貝,值類型賦值拷貝,引用類型句柄拷貝)。深拷貝需實現 ICloneable 接口

代碼示例:相等性與哈希碼演示

using System;
struct A { public int count; }
class B { public int number; }
class C {
    public int integer = 0;
    public override bool Equals(object obj) {
        C c = obj as C;
        return c != null && this.integer == c.integer;
    }
    public override int GetHashCode() { return 2 ^ integer; }
}
class Test {
    public static void Main() {
        // 結構 A:值類型,預設值相等
        A a1, a2; a1.count = 10; a2 = a1;
        Console.Write(a1.Equals(a2)); // True
        Console.WriteLine(Object.ReferenceEquals(a1, a2)); // False

        // 類 B:引用類型,未重寫 Equals,引用相等
        B b1 = new B(), b2 = new B(); b1.number = 10; b2.number = 10;
        Console.Write(b1 == b2); // False
        Console.Write(b1.Equals(b2)); // False
        b2 = b1;
        Console.Write(b1 == b2); // True

        // 類 C:重寫 Equals 和 GetHashCode,值相等
        C c1 = new C(), c2 = new C(); c1.integer = 10; c2.integer = 10;
        Console.Write(c1 == c2); // False
        Console.Write(c1.Equals(c2)); // True
        c2 = c1;
        Console.Write(c1 == c2); // True
    }
}

總結

對類、對象、this 及 System.Object 的深入把握,為掌握 C# 高級特性奠定了堅實基礎。後續將探討成員初始化、內存管理、繼承多態、異常處理等核心主題。

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