200 lines
3.8 KiB
Markdown
200 lines
3.8 KiB
Markdown
|
|
# 密封类
|
|||
|
|
概念:
|
|||
|
|
使用 `sealed` 关键字修饰的类,叫做==密封类==
|
|||
|
|
作用是:==让这个类不能再被其他类继承==
|
|||
|
|
|
|||
|
|
简单理解:
|
|||
|
|
这个类已经是“最终版本”了,别人只能使用它,不能在它的基础上继续派生子类
|
|||
|
|
|
|||
|
|
通常用法:
|
|||
|
|
1. 不希望某个类被继续继承,避免子类乱改行为
|
|||
|
|
2. 类的设计已经完整,不打算给别人扩展
|
|||
|
|
3. 保护程序规范性和安全性
|
|||
|
|
4. 表示某个类型在业务上就是终点,不应该再有更细的子类
|
|||
|
|
|
|||
|
|
语法:
|
|||
|
|
```csharp
|
|||
|
|
sealed class 类名
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
案例:
|
|||
|
|
```csharp
|
|||
|
|
class Enemy
|
|||
|
|
{
|
|||
|
|
public string Name;
|
|||
|
|
|
|||
|
|
public virtual void Attack()
|
|||
|
|
{
|
|||
|
|
Console.WriteLine("敌人攻击");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sealed class Boss : Enemy
|
|||
|
|
{
|
|||
|
|
public override void Attack()
|
|||
|
|
{
|
|||
|
|
Console.WriteLine("Boss发动攻击");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
上面代码中:
|
|||
|
|
- `Boss` 可以继承 `Enemy`
|
|||
|
|
- 但是 `Boss` 被 `sealed` 修饰后,别的类就不能再继承 `Boss`
|
|||
|
|
|
|||
|
|
错误示意:
|
|||
|
|
```csharp
|
|||
|
|
class FinalBoss : Boss
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这样会报错,因为 `Boss` 是密封类,不能作为父类继续被继承
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 密封类还能不能正常使用
|
|||
|
|
可以。
|
|||
|
|
|
|||
|
|
`sealed` 只是不允许别人继承它,==不影响创建对象和调用成员==。
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
sealed class PlayerConfig
|
|||
|
|
{
|
|||
|
|
public int MaxHp = 100;
|
|||
|
|
|
|||
|
|
public void Print()
|
|||
|
|
{
|
|||
|
|
Console.WriteLine(MaxHp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PlayerConfig config = new PlayerConfig();
|
|||
|
|
config.Print();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 密封类和继承
|
|||
|
|
密封类不是说“自己不能继承别人”,而是说“别人不能继承自己”。
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
class Animal
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sealed class Dog : Animal
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这个是可以的:
|
|||
|
|
- `Dog` 继承了 `Animal`
|
|||
|
|
- `Dog` 自己被密封
|
|||
|
|
- 所以以后不能再写 `class Husky : Dog`
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 和普通类的区别
|
|||
|
|
普通类:
|
|||
|
|
```csharp
|
|||
|
|
class A
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class B : A
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
密封类:
|
|||
|
|
```csharp
|
|||
|
|
sealed class A
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// class B : A // 错误,A 不能被继承
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
一句话:
|
|||
|
|
普通类可以当父类,密封类不能当父类
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 密封类和抽象类不能同时用
|
|||
|
|
错误写法:
|
|||
|
|
```csharp
|
|||
|
|
sealed abstract class A
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
原因:
|
|||
|
|
- `abstract` 抽象类的意义是:必须被子类继承后补全实现
|
|||
|
|
- `sealed` 密封类的意义是:不允许被继承
|
|||
|
|
|
|||
|
|
这两个要求互相矛盾,所以不能一起用
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 顺带理解:sealed 也能修饰重写成员
|
|||
|
|
`sealed` 不只可以修饰类,还可以修饰==已经 override 的方法或属性==。
|
|||
|
|
|
|||
|
|
作用是:
|
|||
|
|
允许这个类继续被继承,但是不允许子类继续重写某个成员
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
class Animal
|
|||
|
|
{
|
|||
|
|
public virtual void Speak()
|
|||
|
|
{
|
|||
|
|
Console.WriteLine("动物叫");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class Dog : Animal
|
|||
|
|
{
|
|||
|
|
public sealed override void Speak()
|
|||
|
|
{
|
|||
|
|
Console.WriteLine("狗叫");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class Husky : Dog
|
|||
|
|
{
|
|||
|
|
// 这里不能再 override Speak
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这里要区分:
|
|||
|
|
1. `sealed class Dog`:整个 `Dog` 类不能被继承
|
|||
|
|
2. `sealed override void Speak()`:`Dog` 类还能被继承,但 `Speak` 不能继续被重写
|
|||
|
|
|
|||
|
|
这个内容后面可以和[[多态vob|多态]]、[[密封函数]]一起理解。
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 注意
|
|||
|
|
1. `sealed` 修饰类时,表示这个类==不能被继承==
|
|||
|
|
2. 密封类自己仍然可以继承普通类,也可以实现接口
|
|||
|
|
3. 密封类可以正常创建对象、调用方法、访问属性
|
|||
|
|
4. 密封类不能和 `abstract` 同时使用
|
|||
|
|
5. 如果只是想禁止某个方法继续被重写,可以用 `sealed override`,不一定要把整个类密封
|
|||
|
|
6. 初学阶段不要滥用 `sealed`,只有确定“不应该再被继承”时再用
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 一句话记忆
|
|||
|
|
==sealed class 表示这个类到此为止,后面不能再派生子类。==
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
引用:
|
|||
|
|
1. Microsoft Learn: [sealed (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed)
|
|||
|
|
2. Microsoft Learn: [Inheritance - derive types to create more specialized behavior](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/inheritance)
|
|||
|
|
|
|||
|
|
#密封类
|
|||
|
|
#核心
|