动易网校
| 网站首页 | 系部管理 | 技术文章 | 资料下载 | 人才与社会 | 雁过留声 | 学院论坛 |
程序语言 数据库 电脑艺术 网络技术 软件应用 考试认证
[图文]深入剖析C#继承机制
深入剖析C#继承机制         ★★★
【字体:- +
作者: 佚名 文章来源:本站原创 点击数: 更新时间:2005-10-29

  程序运行输出:

    姓名: 张三
    编号: 111-222-333-444
    成员ID: ABC567EFG23267
    示例:派生类同基类进行通信。

using System ;
public class Parent
{
string parentString;
public Parent( )
{ Console.WriteLine("Parent Constructor.") ; }
public Parent(string myString) {
parentString = myString;
Console.WriteLine(parentString) ;
}
public void print( )
{ Console.WriteLine("I'm a Parent Class.") ; }
}
public class Child : Parent
{
public Child( ) : base("From Derived")
{ Console.WriteLine("Child Constructor.") ; }
public void print( ) {
base.print( ) ;
Console.WriteLine("I'm a Child Class.") ;
}
public static void Main( ) {
Child child = new Child( ) ;
child.print( ) ;
((Parent)child).print( ) ;
}
}

  程序运行输出:

From Derived
Child Constructor.
I'm a Parent Class.
I'm a Child Class.
I'm a Parent Class.

   说明:

   1.派生类在初始化的过程中可以同基类进行通信。

   上面代码演示了在子类的构造函数定义中是如何实现同基类通信的。分号":"和关键字base用来调用带有相应参数的基类的构造函数。输出结果中,第一行表明:基类的构造函数最先被调用,其实在参数是字符串"From Derived"

   2.有时,对于基类已有定义的方法,打算重新定义自己的实现。

   Child类可以自己重新定义print( )方法的实现。Childprint( )方法覆盖了Parent中的 print 方法。结果是:除非经过特别指明,Parent类中的print方法不会被调用。

   3.Child类的 print( ) 方法中,我们特别指明:调用的是Parent类中的 print( ) 方法。

   方法名前面为"base",一旦使用"base"关键字之后,你就可以访问基类的具有公有或者保护权限的成员。 Child类中的print( )方法的执行结果出现上面的第三行和第四行。

   4.访问基类成员的另外一种方法是:通过显式类型转换。

   在Child类的Main( )方法中的最后一条语句就是这么做的。记住:派生类是其基类的特例。这个事实告诉我们:可以在派生类中进行数据类型的转换,使其成为基类的一个实例。上面代码的最后一行实际上执行了Parent类中的 print( )方法。

   (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 修饰符的使用。同时也说明了如何使用完全限定名访问基类的隐藏成员。

上一页  [1] [2] [3] [4] 下一页  


::发表评论::
 姓 名:
 评 分: 1分 2分 3分 4分 5分
 评论内容:
请您发表评论

关于深入剖析C#继承机制的最新评论:

  • 上一篇文章: C# 编码规范和编程好习惯

  • 下一篇文章: .NET Framework 2.0 新特性
  • Copyright(C)2005 版权所有:重庆信息技术职业学院--软件工程学院
    Template design to 久久设计 for 1024x768 to MS-IE6 Site powered by powereasy