什麼是密封類別(Sealed Class)?
sealed:密封類別,不允許被繼承,但能夠繼承其他的類別。
「密封類別(Sealed Class)」其主要作用在於「限制某一類別不能夠被繼承(衍生)」,一旦類別宣告成「密封類別」,就表示該密封類別不可能有子類別(衍生類別)。
Sealed 密封類別,表示它不能被別人繼承,但它能去繼承別人。
1
2
3
4
5
6
7
8
//Sealed 密封類別- 能被別人繼承,但他能去繼承別人
public sealed class Teacher : Person {
}
//沒有東西可以讓你繼承,硬要繼承,就會報錯
//Error: 'Test': 無法衍生自密封類型 'Teacher'
public class Test: Teacher {
}
若強制將某類別繼承 Sealed 密封類別 就會報錯「無法衍生自密封類型 」。
sealed 不能被繼承
它有一個最大的特點,就是不能被繼承。
1
2
public sealed class Test { } //密封類別(Sealed Class)
public class Person : Test { } //報錯,密封類不能被繼承
Error 錯誤訊息:「’Person’: 無法衍生自密封類型 ‘Test’」。
sealed 可以繼承別人
但它可以繼承別人
1
2
3
//密封類別(Sealed Class)繼承 Person
public sealed class Test: Person { }
public class Person { }
密封類別 vs 密封成員
- 使用
sealed關鍵字 - 防止類別繼承、防止派生類重寫
sealed修飾符不僅可以用來修飾class,同樣也可以修飾類成員
它可以防止當前的類別Class被繼承,或者防止衍生類(子類)在繼承過程中重寫某一個方法,sealed 修飾符不僅可以用來修飾class,同樣也可以修飾類的成員。
- 如果
sealed關鍵字使用在class上,這個類別將無法被別人繼承。 - 如果
sealed關鍵字使用在Method上,這個方法將無法被重寫。
類別 Class 加上 sealed
如果sealed關鍵字使用在類別 class 上,這個類別將無法被別人繼承。
例如:A類別 加上 sealed關鍵字,那麼這個A就不能被其他的 class 繼承了。
1
2
sealed class A: B {} //密封類別A 可以繼承 B
class B {} //但類別B 不能繼承A,因為密封類別 不能被別人繼承
方法 Mthod 加上 sealed
如果sealed關鍵字使用在 Method上,這個方法將無法被重寫。
或者,我們也可以把sealed修飾符加在方法上,這個時候其他的class 在繼承 該類別的時候,就不可以 重寫這個方法了
例如,三個類別 X、Y、Z,
X 提供虛方法讓繼承它的類別可以重寫,Y繼承X後,我們把sealed修飾符加在它的 F()方法 上,這個時候Z class 在繼承 Y 的時候,就不可以重寫 F() 這個方法了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class X
{ //虛方法
protected virtual void F() { Console.WriteLine("X.F"); }
protected virtual void F2() { Console.WriteLine("X.F2"); }
}
class Y : X
{ //重寫虛方法,F() 方法加上 sealed 密封,不讓它被重寫
sealed protected override void F() { Console.WriteLine("Y.F"); }
protected override void F2() { Console.WriteLine("Y.F2"); }
}
class Z : Y
{ // 硬要重寫 F()方法,就會報錯
// 錯誤訊息:無法重寫繼承的成員 F(),因為已密封
// Attempting to override F causes compiler error CS0239.
// protected override void F() { Console.WriteLine("Z.F"); }
// Overriding F2 is allowed.
protected override void F2() { Console.WriteLine("Z.F2"); }
}
類別Y,將F()方法加上sealed 密封,不讓它被重寫,
類別Z 繼承Y,如果硬要重寫 F()方法,就會報錯,
錯誤訊息:無法重寫繼承的成員 F(),因為已密封
(Attempting to override F causes compiler error CS0239.)
所以,
sealed修飾符跟abstract修飾符剛好相反。
※ 套用至方法或屬性時,sealed修飾詞必須一律與override搭配使用。
可以使用 sealed 的場景
- 當你確定某些類別不會有子類別(衍生類別),就可以宣告成密封類別。(執行時期時,能得到較佳的執行效能)
- 靜態類
- 需要儲存敏感的數據
- 虛方法太多,重寫的代價過高的時候
- 追求性能提升 (???)
MSDN - sealed (C# 參考)
[C# 筆記] Sealed 密封類別 by R
[C# 筆記] Sealed 密封類 vs 密封成員 by R
[C# 筆記] 關鍵字 by R