简介
sealed 关键字在 C# 中用于阻止继承和重写,通常用于类或方法,以增强代码的安全性和稳定性。
sealed 用于类
当一个类被 sealed 修饰时,该类不能被继承。这样可以防止其他类扩展它的功能,从而保护类的实现。
sealed class MyClass
{public void Show(){Console.WriteLine("Hello from MyClass");}
}
不能继承 MyClass,否则会编译报错
class DerivedClass : MyClass // 报错:无法从密封类 'MyClass' 派生
{
}
适用场景
-
安全性:防止恶意或意外的继承,保护关键逻辑不被更改。
-
优化性能:密封类可以让
JIT(Just-In-Time编译器)优化方法调用,提高执行速度。
sealed 用于方法
如果一个方法在基类中是 virtual 或 override,可以使用 sealed 防止子类进一步重写它。
class BaseClass
{public virtual void Show(){Console.WriteLine("BaseClass Show");}
}class DerivedClass : BaseClass
{public sealed override void Show(){Console.WriteLine("DerivedClass Show");}
}class SubDerivedClass : DerivedClass
{// 报错:无法重写密封的方法 "Show"// public override void Show() { }
}
适用场景
-
防止进一步重写:如果一个方法被
sealed了,子类无法重写它,确保逻辑稳定。 -
提高性能:密封方法可以提高方法调用效率,因为
JIT编译器可以直接调用它,而不需要查找虚方法表(vtable)。
sealed 结合 abstract
-
sealed不能和abstract一起用于类,因为抽象类必须允许继承,而密封类不能被继承。 -
但是,抽象类的
override方法可以是sealed,防止进一步重写。
abstract class AbstractClass
{public abstract void Display();
}class ConcreteClass : AbstractClass
{public sealed override void Display(){Console.WriteLine("ConcreteClass Display");}
}class SubConcreteClass : ConcreteClass
{// 报错:无法重写密封方法 "Display"// public override void Display() { }
}
sealed 结合 struct
C# 中,所有 struct 默认是 sealed,不能被继承,所以不需要显式声明 sealed。
struct MyStruct
{public int Value;
}// 报错:结构不能被继承
// class DerivedStruct : MyStruct { }
总结
| 用法 | 作用 | 示例 |
|---|---|---|
sealed 类 | 防止继承 | sealed class MyClass { } |
sealed 方法 | 防止方法被进一步重写 | public sealed override void Method() { } |
sealed + abstract | 限制抽象方法的继承 | public sealed override void AbstractMethod() { } |
sealed 结构体 | 默认不能被继承 | struct MyStruct { } |
C# sealed 与 Java final 比较
类(防止继承)
- C#:使用 sealed
sealed class MyClass
{public void Show(){Console.WriteLine("Hello from MyClass");}
}// 下面的代码会报错
// class DerivedClass : MyClass { } // 错误:无法从密封类 'MyClass' 派生
- Java:使用 final
final class MyClass {void show() {System.out.println("Hello from MyClass");}
}// 下面的代码会报错
// class DerivedClass extends MyClass {} // 错误:无法继承 final 类
C# 的 sealed class 和 Java 的 final class 作用一样,都用于防止类被继承。
方法(防止子类重写)
- C#:使用 sealed
class BaseClass
{public virtual void Show(){Console.WriteLine("BaseClass Show");}
}class DerivedClass : BaseClass
{public sealed override void Show(){Console.WriteLine("DerivedClass Show");}
}// 下面的代码会报错
// class SubDerivedClass : DerivedClass
// {
// public override void Show() { } // 错误:无法重写密封的方法 "Show"
// }
- Java:使用 final
class BaseClass {public void show() {System.out.println("BaseClass Show");}
}class DerivedClass extends BaseClass {@Overridepublic final void show() {System.out.println("DerivedClass Show");}
}// 下面的代码会报错
// class SubDerivedClass extends DerivedClass {
// @Override
// public void show() {} // 错误:无法重写 final 方法
// }
C# 的 sealed override 和 Java 的 final method 作用相同,都用于防止方法被子类重写。
变量(防止修改)
Java 支持 final 变量,C# 需要用 readonly 或 const 实现类似功能。
- Java:final 变量
class Example {final int number = 10; // 只能赋值一次void changeNumber() {// 报错:无法修改 final 变量// number = 20;}
}
- C#:使用 readonly 或 const
class Example
{public readonly int number = 10; // 只能在构造函数中赋值public const int constNumber = 20; // 编译时常量,必须初始化public Example(){number = 15; // 允许// constNumber = 30; // 报错:const 变量不能修改}
}
-
Java的final可以用于变量,防止变量被修改。 -
C#没有final变量,但可以用readonly(运行时常量)或const(编译时常量)来替代。
