2) 隐藏基类成员
  想想看,如果所有的类都可以被继承,继承的滥用会带来什么后果?类的层次结构体系将变得十分庞,大类之间的关系杂乱无章,对类的理解和使用都会变得十分困难。有时候,我们并不希望自己编写的类被继承。另一些时候,有的类已经没有再被继承的必要。C#提出了一个密封类(sealed class)的概念,帮助开发人员来解决这一问题。
  密封类在声明中使用sealed 修饰符,这样就可以防止该类被其它类继承。如果试图将一个密封类作为其它类的基类,C#将提示出错。理所当然,密封类不能同时又是抽象类,因为抽象总是希望被继承的。
  在哪些场合下使用密封类呢?密封类可以阻止其它程序员在无意中继承该类。而且密封类可以起到运行时优化的效果。实际上,密封类中不可能有派生类。如果密封类实例中存在虚成员函数,该成员函数可以转化为非虚的,函数修饰符virtual 不再生效。
  让我们看下面的例子:
bstract class A
{
public abstract void F( ) ;
}
sealed class B: A
{
public override void F( ) 
{ // F 的具体实现代码 }
} 
  如果我们尝试写下面的代码
class C: B{ }
  C#会指出这个错误,告诉你B 是一个密封类,不能试图从B 中派生任何类。
  (3) 密封方法
  我们已经知道,使用密封类可以防止对类的继承。C#还提出了密封方法(sealedmethod) 的概念,以防止在方法所在类的派生类中对该方法的重载。对方法可以使用sealed 修饰符,这时我们称该方法是一个密封方法。
  不是类的每个成员方法都可以作为密封方法密封方法,必须对基类的虚方法进行重载,提供具体的实现方法。所以,在方法的声明中,sealed 修饰符总是和override 修饰符同时使用。请看下面的例子代码:
using System ;
class A
{
public virtual void F( ) 
{ Console.WriteLine("A.F") ; }
public virtual void G( ) 
{ Console.WriteLine("A.G") ; }
}
class B: A
{
sealed override public void F( ) 
{ Console.WriteLine("B.F") ; }
override public void G( ) 
{ Console.WriteLine("B.G") ; }
}
class C: B
{
override public void G( ) 
{ Console.WriteLine("C.G") ; }
}  
  类B 对基类A 中的两个虚方法均进行了重载,其中F 方法使用了sealed 修饰符,成为一个密封方法。G 方法不是密封方法,所以在B 的派生类C 中,可以重载方法G,但不能重载方法F。
  (4) 使用 new 修饰符隐藏基类成员
  使用 new 修饰符可以显式隐藏从基类继承的成员。若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并用 new 修饰符修饰它。
  请看下面的类:
public class MyBase 
{
public int x ;
public void MyVoke() ;
} 
  在派生类中用 MyVoke名称声明成员会隐藏基类中的 MyVoke方法,即:
public class MyDerived : MyBase
{ new public void MyVoke (); } 
  但是,因为字段 x 不是通过类似名隐藏的,所以不会影响该字段。 
  通过继承隐藏名称采用下列形式之一: 
   a、引入类或结构中的常数、指定、属性或类型隐藏具有相同名称的所有基类成员。 
   b、引入类或结构中的方法隐藏基类中具有相同名称的属性、字段和类型。同时也隐藏具有相同签名的所有基类方法。 
   c、引入类或结构中的索引器将隐藏具有相同名称的所有基类索引器。 
  注意:在同一成员上同时使用 new 和 override 是错误的。同时使用 new 和 virtual 可保证一个新的专用化点。在不隐藏继承成员的声明中使用 new 修饰符将发出警告。
  示例1:在该例中,基类 MyBaseC 和派生类 MyDerivedC 使用相同的字段名 x,从而隐藏了继承字段的值。该例说明了 new 修饰符的使用。同时也说明了如何使用完全限定名访问基类的隐藏成员。
using System ;
public class MyBase 
{
public static int x = 55 ;
public static int y = 22 ;
}
public class MyDerived : MyBase
{
new public static int x = 100; // 利用new 隐藏基类的x
public static void Main() 
{
// 打印x:
Console.WriteLine(x);
//访问隐藏基类的 x:
Console.WriteLine(MyBase.x);
//打印不隐藏的y:
Console.WriteLine(y);
}
} 
  输出: 100 55 22
  如果移除 new 修饰符,程序将继续编译和运行,但您会收到以下警告:
The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'.
  如果嵌套类型正在隐藏另一种类型,如下例所示,也可以使用 new 修饰符修改此嵌套类型。