一、類型的各種成員
|
分類
|
成員
|
是否支持靜態(static)
|
是否可反射訪問
|
説明
|
|
1. 數據成員 |
常量(Constants) |
✅(隱式靜態)
|
✅(有限,通常是編譯期替換)
|
用 |
|
字段(Fields) |
✅(支持靜態字段)
|
✅
|
變量,可以是實例字段或靜態字段
|
|
|
2. 函數成員 |
方法(Methods) |
✅(支持靜態方法)
|
✅
|
行為邏輯,可以是實例方法或靜態方法
|
|
操作符重載(Operator Overloads) |
✅(必須靜態)
|
✅
|
自定義操作符行為,如 |
|
|
轉換運算符(Conversion Operators) |
✅(必須靜態)
|
✅
|
自定義類型間轉換,如 |
|
|
3. 封裝與訪問成員 |
屬性(Properties) |
✅(支持靜態屬性)
|
✅
|
帶有 |
|
4. 事件成員 |
事件(Events) |
✅(支持靜態事件)
|
✅
|
用於發佈/訂閲通知機制,如 |
|
5. 構造與初始化成員 |
實例構造器(Instance Constructors) |
❌(只能是實例)
|
✅
|
用於創建對象實例,如 |
|
類型構造器(靜態構造器 / Type Initializer) |
✅(靜態,唯一)
|
✅
|
用於初始化靜態成員,自動調用,如 |
|
|
6. 類型本身(元數據) |
類型(Type) |
—
|
✅(核心)
|
表示一個類型本身,是反射和動態系統的核心,如 |
常量
定義:使用 const關鍵字聲明,值在編譯時確定且不可更改。
public class MyConstants
{
public const int MaxValue = 100;
}
字段
定義:類或結構體中聲明的變量,可以是 實例字段 或 靜態字段。
public class Person
{
public static int Count = 0; // 靜態字段
public string Name; // 實例字段
}
實例構造器
定義:用於創建類型實例的特殊方法,如 public MyClass() { }
public class MyClass
{
public MyClass() { }
public MyClass(int id) { }
}
類型構造器
用於初始化靜態成員,每個類型有且只有一個,無參數,自動調用。
public class Logger
{
static Logger() { Console.WriteLine("靜態構造器被調用"); }
}
方法
定義:類中定義的行為或邏輯單元,可以是 實例方法 或 靜態方法。
public class Calculator
{
public static int Add(int a, int b) => a + b;
public int Multiply(int a, int b) => a * b;
}
操作符重載
定義:自定義操作符行為,如 +, -, ==, !=等。 必須為靜態方法
public class Vector
{
public static Vector operator +(Vector a, Vector b) { ... }
}
轉換符重載
定義:定義類型之間的 隱式或顯式轉換,如 implicit operator int(MyClass c) 必須為靜態方法
public class MyClass
{
public static implicit operator int(MyClass c) => 42;
}
屬性
定義:一種帶有 get和/或 set訪問器的成員,提供對字段的受控訪問。
public class Account
{
public static decimal InterestRate { get; set; }
public string Owner { get; set; }
}
事件
定義:允許訂閲和觸發通知的成員,通常是委託類型,如 event Action OnChange;
public class Button
{
public static event Action OnClick;
}
類型
定義:表示一個類型本身,是反射和動態系統的核心,比如 typeof(string)或 obj.GetType()
Type t = typeof(string);
TypeInfo ti = t.GetTypeInfo();
二、類型的可見性
|
訪問修飾符
|
説明
|
可訪問範圍
|
|
|
公開的,任何代碼都可以訪問 |
任何地方(本程序集、其他程序集) |
|
|
私有的,只有當前類內部可以訪問 |
僅限當前類內部 |
|
|
受保護的,當前類及其派生類可以訪問 |
當前類 + 子類(無論是否在同一個程序集) |
|
|
內部的,只有當前程序集(Assembly)內可以訪問 |
同一個程序集內(如同一個項目) |
|
|
受保護或內部的(二選一即可訪問) 即: |
當前程序集內任意代碼或任意程序集中的子類 |
|
|
私有且受保護的(僅當前程序集中的子類可訪問) |
C#要求原始成員和重寫成員具有相同的可訪問性。
class BaseClass
{
// 原始方法是 public
public virtual void Show()
{
Console.WriteLine("Base Show");
}
}
class DerivedClass : BaseClass
{
// 錯誤:嘗試將 public 方法重寫為 protected(縮小了可訪問性)
// 編譯錯誤 “DerivedClass.Show()”: 當重寫“public”繼承成員“BaseClass.Show()”時,無法更改訪問修飾符
protected override void Show()
{
Console.WriteLine("Derived Show");
}
}
三、幾個關鍵字
|
關鍵字
|
修飾類型
|
修飾成員
|
主要作用
|
|
abstract |
類
|
方法/屬性/事件
|
強制派生類實現
|
|
virtual |
❌
|
方法/屬性/事件
|
允許派生類重寫
|
|
override |
❌
|
方法/屬性/事件
|
重寫基類虛成員
|
|
sealed |
類
|
重寫的方法
|
防止進一步繼承/重寫
|
|
new |
嵌套類型
|
方法/屬性/字段
|
顯式隱藏基類成員
|
- 普通方法:不能重寫,適合固定邏輯。
- 虛方法:可以重寫,適合“有默認實現,但允許定製”的場景。
- 抽象方法:沒有實現,強制子類實現,適合“只定義接口,不提供默認行為”的場景。
abstract的例子
using System;
// 抽象類 - 不能實例化
public abstract class Shape
{
// 抽象類可以有字段,但不能有抽象字段
protected string name;
// 抽象屬性 - 必須在派生類中實現
public abstract double Area { get; }
public abstract double Perimeter { get; }
// 抽象方法 - 必須在派生類中實現
public abstract void Draw();
// 普通方法 - 可以提供默認實現
public void DisplayInfo()
{
Console.WriteLine($"形狀: {name}, 面積: {Area}, 周長: {Perimeter}");
}
// 抽象類不能有抽象構造函數
// public abstract Shape(); // 編譯錯誤
}
// 具體實現類
public class Circle : Shape
{
private double radius;
public Circle(double r)
{
name = "圓形";
radius = r;
}
// 必須實現所有抽象成員
public override double Area => Math.PI * radius * radius;
public override double Perimeter => 2 * Math.PI * radius;
public override void Draw()
{
Console.WriteLine($"繪製半徑為 {radius} 的圓形");
}
}
public class Rectangle : Shape
{
private double _width,_height;
public Rectangle(double width, double height)
{
name = "矩形";
_width = width;
_height = height;
}
public override double Area => _width * _height;
public override double Perimeter => 2 * (_width + _height);
public override void Draw()
{
Console.WriteLine($"繪製 {width}x{height} 的矩形");
}
}
virtual 例子
using System;
public class Animal
{
// 虛屬性 - 可以在派生類中重寫
public virtual string Species { get; set; } = "未知動物";
// 虛方法 - 可以在派生類中重寫
public virtual void MakeSound()
{
Console.WriteLine("動物發出聲音");
}
// 虛方法帶默認實現
public virtual void Move()
{
Console.WriteLine("動物移動");
}
// 不能將字段聲明為virtual
// public virtual string name; // 編譯錯誤
}
public class Dog : Animal
{
public Dog()
{
Species = "犬科";
}
// 重寫虛方法
public override void MakeSound()
{
Console.WriteLine("汪汪汪!");
}
public override void Move()
{
Console.WriteLine("狗用四條腿奔跑");
}
}
public class Bird : Animal
{
public Bird()
{
Species = "鳥類";
}
public override void MakeSound()
{
Console.WriteLine("啾啾啾!");
}
public override void Move()
{
Console.WriteLine("鳥在天空中飛翔");
}
}
sealed例子
using System;
// 密封類 - 不能作為基類
public sealed class SealedClass
{
public void Method()
{
Console.WriteLine("密封類的方法");
}
}
// 編譯錯誤 - 不能繼承密封類
// public class DerivedSealed : SealedClass { } // 錯誤
// 密封方法示例
public class BaseVehicle
{
public virtual void StartEngine()
{
Console.WriteLine("引擎啓動");
}
}
public class Car : BaseVehicle
{
// 密封重寫的方法 - 不能再被重寫
public sealed override void StartEngine()
{
Console.WriteLine("汽車引擎啓動 - 帶鑰匙點火");
}
// 普通虛方法仍可被重寫
public virtual void Drive()
{
Console.WriteLine("駕駛汽車");
}
}
public class SportsCar : Car
{
// 編譯錯誤 - 不能重寫密封方法
// public override void StartEngine() { } // 錯誤
// 可以重寫其他虛方法
public override void Drive()
{
Console.WriteLine("高速駕駛跑車");
}
}