密封类(sealed)
C#提供一种不能被继承的类,称为密封类。密封类的声明方法是在类名前加上sealed修饰符。修饰符abstract和sealed不能同时使用。
密封类在声明中使用sealed 修饰符,这样就可以防止该类被其它类继承。如果试图将一个密封类作为其它类的基类,C#将提示出错。理所当然,密封类不能同时又是抽象类,因为抽象总是希望被继承的。
sealed 修饰符可以应用于类、实例方法和属性。密封类不能被继承。密封方法会重写基类中的方法,但其本身不能在任何派生类中进一步重写。当应用于方法或属性时,sealed 修饰符必须始终与 override 一起使用。
在类声明中使用 sealed 修饰符可防止继承此类,sealed 的class只能实例化。例如:
sealed class SealedClass
{
public int x;
public int y;
}
将密封类用作基类或将 abstract 修饰符与密封类一起使用是错误的。
结构是隐式密封的;因此它们不能被继承。
// cs_sealed_keyword.cs
using System;
sealed class SealedClass
{
public int x;
public int y;
}
class MainClass
{
static void
{
SealedClass sc = new SealedClass();
sc.x = 110;
sc.y = 150;
Console.WriteLine("x = {0}, y = {1}", sc.x, sc.y);
Console.ReadKey();
}
}
在前面的示例中,如果试图通过使用下面的语句从密封类继承:
class MyDerivedC: MyClass {} // Error
将收到错误信息:
'MyDerivedC' cannot inherit from sealed class 'MyClass'.
当创建一个类时,有时需要让该类包含一些特殊的方法,该类对这些方法不提供具体实现,但该类的派生类必须实现这些方法,这些方法在C#中称为抽象方法。抽象方法必须是一个没有被实现的空方法。包含抽象方法的类称为抽象类,抽象类中也可以包含非抽象方法。
因为抽象类是用来作为基类的,所以不能直接被外部程序实例化,而且也不能被密封。
声明抽象方法的基本语法为:
[访问修饰符] abstract 返回类型 方法名([参数列表]);
声明抽象类的基本语法为:
[访问修饰符] abstract 类名{ }
例如:
public abstract class Anmial
{
protected double Weight;
public abstract void Eat(); //抽象方法
}
当派生类从抽象类中继承一个抽象方法时,派生类必须重载该抽象方法。下面代码中,Cat类派生自Animal类,并通过使用override关键词重载了Animal类中的Eat方法。
public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Eat fish");
}
}
(1)接口实现
一个接口定义一个协议。实现接口的类或结构必须遵守其协议。在某种程度上,接口像一个抽象类。和任何类一样,接口可以定义方法、属性、事件等。但是,接口不提供成员的实现。实现接口的任何类都必须提供接口中所声明的抽象成员的定义。
界面声明的格式为:[访问修饰符] interface 界面名 [:基接口] {接口体}
接口体定义与类相似。要注意的是,接口的成员可以是方法、属性、事件和索引,但不能是常数、字段、运算符、实例构造函数、析构函数或类型,也不能是任何种类的静态成员。此外,对界面还有以下限制:
(1)接口可以用任何可访问性来声明,但接口成员必须全都具有公共可访问性。
(2)不能向成员或接口自身附加安全性权限。
(3)接口可以定义类构造函数,但不能定义实例构造函数。
接口可以由类和结构实现。实现的接口的标识符出现在类的基列表中。
如下示例中,类 EditBox 从类 Control 派生,并且同时实现IControl和IDataBound。
interface IDataBound
{
void Bind(Binder b);
}
public class EditBox: Control, IControl, IDataBound
{
public void Paint() {...}
public void Bind(Binder b) {...}
}
(2)接口的用处
一个设计良好的接口可以包含一个紧密相关的功能集合,这些功能定义了一些特定的行为。当一个类实现了这个接口时,该类就实现了这些行为。可以为接口扩展新的增强实现,而不破坏现有的代码,因此使用接口使得程序的兼容性增强,另外也可以通过开发新的接口或接口的新的实现来增强功能。界面的用处具体体现在下面几个方面:
(1)通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系。
(2)通过接口指明多个类需要实现的方法。
(3)通过接口了解对象的交互接口,而无需了解对象所对应的类。
(3)接口与抽象类的比较
抽象类是一种不能实例化的类,通常是部分实现的或完全不实现的,从而它可以用来封装类的通用功能。
与抽象类不同的是,接口是一个完全抽象的成员集合。这个成员集合为相关操作定义了一个规则。接口的实现完全留给类设计者去完成。
使用抽象类的好处是:通过更新父类,所有派生类都将自动进行相应更新。而接口在创建后就不能再更改了。如果需要修改接口,则必须创建新的接口。
(To be continued)
评论