C#中继承和构造函数

一个类继承自另外一个类,他们的构造函数改怎么办?

首先必须先声明:构造函数是不能继承的

我们先看一段代码:第一段代码没有构造函数,第二段有一个,第三段有两个。从他们的MSIL可以看出,有几个构造函数就有几个.ctor的il函数。

即使你没有构造函数,编译器也会调用一个空的构造函数。让我们仔细瞧瞧MSIL代码:

我们可以看到每个IL中都有   instance void [mscorlib]System.Object::.ctor()

由此我们可以得出。不管你有几个构造器,你都必须执行父类的构造函数,才能执行当前构造函数;同样对于继承,必须先实现父类的构造函数,才能执行自己的.ctor

如果我们写一个空的构造函数 public class  someType{  public someType(){   }  } 

就是public class  someType{  public someType():base(){   }  }  。这种方法是调用(基)类中其他的构造器

(方法一,二 都只有一个.ctor)(方法三:有两个.ctor)

  static void Main(string[] args)
        {
            Console.WriteLine("nihao");
        }

.method public hidebysig specialname rtspecialname
        instance void  .ctor() cil managed
{
  // 代码大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
} // end of method Program::.ctor

  

 class Program
    {
        private Int32 i;
        public Program(Int32 i)
        {
            this.i = i;
        }
        static void Main(string[] args)
        {
            Console.WriteLine("nihao");
        }
    }

.method public hidebysig specialname rtspecialname
        instance void  .ctor(int32 i) cil managed
{
  // 代码大小       17 (0x11)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldarg.1
  IL_000a:  stfld      int32 MSIL.Program::i
  IL_000f:  nop
  IL_0010:  ret
} // end of method Program::.ctor

  

class Program
    {
        private Int32 i;
        private Int32 j;
        public Program(Int32 i)
        {
            this.i = i;
        }
        public Program(Int32 i, Int32 j)
        {
            this.i = i;
            this.j = j;
        }
        static void Main(string[] args)
        {
            Console.WriteLine("nihao");
        }
    }

.method public hidebysig specialname rtspecialname 
        instance void  .ctor(int32 i,
                             int32 j) cil managed
{
  // 代码大小       24 (0x18)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldarg.1
  IL_000a:  stfld      int32 MSIL.Program::i
  IL_000f:  ldarg.0
  IL_0010:  ldarg.2
  IL_0011:  stfld      int32 MSIL.Program::j
  IL_0016:  nop
  IL_0017:  ret
} // end of method Program::.ctor

.method public hidebysig specialname rtspecialname 
        instance void  .ctor(int32 i) cil managed
{
  // 代码大小       17 (0x11)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldarg.1
  IL_000a:  stfld      int32 MSIL.Program::i
  IL_000f:  nop
  IL_0010:  ret
} // end of method Program::.ctor

首先我们看看一个关于this()/base() 也就是本构造器调用其他构造器的例子,注意调用其他构造器在前,再执行自己的代码

 class Program
    {
        private Int32 i;
        private Int32 j;
        private string m;

        public Program()   //初始化所有变量
        {
            this.i = 1;
            this.j = 2;
            this.m = "nimei";
        }

        public Program(Int32 i):this()   //构造单个变量
        {
            this.i = i;
        }
        public Program(Int32 j): this()
        {
            this.i = j;
        }
        public Program(string m): this()
        {
            this.m = m;
        }
        static void Main(string[] args)
        {
            Console.WriteLine("nihao");
        }
    }

  三、接下来贴出搞了我一下午的一个例子。在上篇博客中讲到用范型实现一个链表。但是那种实现方式中,链表的每个值必须都是同一个类型,本例中实现任意类型

直接贴代码,下面解释

   public class baseNode {
        protected baseNode bNode;
        public baseNode(baseNode bn)
        {
            this.bNode = bn;
        }
    }
   public class Node2<T>:baseNode
    {

        private T _data;

        public Node2(T data):this(data,null)  //:base(null) 注意在构造之前要实现父类的构造函数
        {  
            this._data = data;
        }
        public Node2(T data,baseNode bNode):base(bNode)
        {
            this._data = data;
        }
        public override string ToString()
        {
            return _data.ToString() + (bNode != null ? bNode.ToString() : null);
        }

    }

   public class LeaderFunction2
   {
       public void function()
       {
         
           baseNode node = new Node2<char>('A');
           node = new Node2<string>("B", node);
           node = new Node2<Int32>(3354435, node);
           node = new Node2<char>('D', node);
           node = new Node2<char>('E', node);

           Console.WriteLine(node.ToString());
           Console.ReadKey();
       }

   }

 这个例子理解了一下午,搞不懂其内部机制,想用MSIL解释,看到那些伪汇编头都大,主要是由于自己的基础知识不扎实啊!

本例中:第一,注意继承要实现父类的构造

           第二,为什么这样写可以实现:

                    

其实还是和之前的一样,虽然到了最后node指向最后一个 NOde2对象,但是之前的对象都没有销毁,地址保存在下个node2中的basenode.bNodeN中。

 

posted @ 2013-08-08 17:33  Jackvin  阅读(2787)  评论(0编辑  收藏  举报