分享

c#中abstract、override、new、virtual、sealed使用和示例 .

 程序积累 2014-05-14

abstract

     修饰类名为抽象类,修饰方法为抽象方法。如果一个类为抽象类,则这个类智能是其他某个类的基类。抽象方法在抽象类中没有函数体。抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法。

     抽象类有如下特征:

  • 抽象类不能实例化
  • 抽象类的派生类必须实现所有抽象方法
  • 抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法

抽象方法:
  • 抽象方法是隐式的虚方法
  • 只允许在抽象类中使用抽象方法声明
  • 抽象方法在抽象类中没有方法体
  • 在抽象方法声明中,不能使用static或者virtual修饰符
  1. abstract class A //abstract 关键字在class前面   
  2. {  
  3.     public abstract void run();//方法是将关键字abstract 添加到方法的返回类型的前面   
  4. }  

override
    override关键字提供派生类对基类方法的新的实现,重写的基类方法必须和基类的方法有着相同的签名(函数名、返回值、参数列表相同)。
    override关键字不可以重写基类非virtual修饰的方法和static修饰的静态方法。
    派生类的override方法和基类的virtual方法必须有相同的访问权限。不能用修饰符new、static、virtual或者abstract修饰override方法。
    派生类的override方法重写的基类方法必须是virtual、abstract或者override的。
     
  1. abstract class A  
  2. {  
  3. public virtual void MethodA()  
  4. {  
  5.      //do something   
  6. }  
  7. public abstract void run();  
  8. }  
  9.      public class B:A  
  10. {  
  11. public override void MethodA()  
  12. {  
  13.     //do somthing   
  14. }  
  15. public virtual void run()  
  16. {  
  17.     //do something   
  18. }  
  19. }  


new
    c#中,new的关键字主要有三个功能:
  1. 作为运算符用来创建类的一个对象。 Class obj = new Class();
  2. 作为修饰符。
  3. 用于在泛型声明中约束可能用作类型参数的参数类型。(这个不太清楚)
      在这里主要介绍第2个功能,作为修饰符的作用。
      new声明的方法,当使用子类的类型来调用的时候,它会运行子类的函数,而如果类型是基类的话,被隐藏的基类函数会被调用。
       而子类中函数使用override的时候,则当使用子类的类型来调用的是,它会运行子类的函数,类型是基类的时候,仍会调用子类函数。


       如下例:
       
  1. // Define the base class   
  2.   class Car  
  3.   {  
  4.       public virtual void DescribeCar()  
  5.       {  
  6.           System.Console.WriteLine("Four wheels and an engine.");  
  7.       }  
  8.   }  
  9.   // Define the derived classes   
  10.   class ConvertibleCar : Car  
  11.   {  
  12.       public new void DescribeCar()  
  13.       {  
  14.           System.Console.WriteLine("A roof that opens up.");  
  15.       }  
  16.   }  
  17.   
  18.   
  19.   class Minivan : Car  
  20.   {  
  21.       public override void DescribeCar()  
  22.       {  
  23.           System.Console.WriteLine("Carries seven people.");  
  24.       }  
  25.   }  
  26.   public class Program  
  27.   {  
  28.       public static void Main()  
  29.       {  
  30.           Car car1 = new Car();  
  31.           car1.DescribeCar();  
  32.           System.Console.WriteLine("----------");  
  33.   
  34.   
  35.           Car car2 = new ConvertibleCar();  
  36.           car2.DescribeCar();  
  37.           System.Console.WriteLine("----------");  
  38.   
  39.   
  40.           Car car3 = new Minivan();  
  41.           car3.DescribeCar();  
  42.           System.Console.WriteLine("----------");  
  43.           System.Console.ReadKey();  
  44.       }  
  45.   }  


virtual
      virtual 关键字允许在派生类中重写这些对象。默认情况下,方法是非虚拟的,不可以重写非虚方法,virtual关键字不可以与static、abstract、private、override一起使用。virtual关键字又是和override紧密不可分的,如果要实现virtual方法就必须要使用override或new关键字(上文已经指出new和override产生的机理不同)。
     

sealed
     
        当对一个类应用sealed修饰符时,此修饰符会阻止其他类从该类继承。
    sealed 方法必须与override连用,也就是说实现sealed方法的类的父类必须实现了此方法。
    sealed关键字有两个作用:
    1 密封类不能被继承。
    2 密封方法重写基类中的方法,但其本身不能在任何派生类中进一步重写

   sealed实例:
    
  1. class X  
  2.   
  3.     {  
  4.         protected virtual void F() { Console.WriteLine("X.F"); }  
  5.         protected virtual void F2() { Console.WriteLine("X.F2"); }  
  6.     }  
  7.     class Y : X  
  8.     {  
  9.         sealed protected override void F() { Console.WriteLine("Y.F"); }  
  10.         protected override void F2() { Console.WriteLine("X.F3"); }  
  11.     }  
  12.     class Z : Y  
  13.     {  
  14.         // Attempting to override F causes compiler error CS0239.   
  15.         // protected override void F() { Console.WriteLine("C.F"); }//sealed修饰的方法是不允许继承的   
  16.   
  17.         // Overriding F2 is allowed.   
  18.         protected override void F2() { Console.WriteLine("Z.F2"); }  
  19.     }  


整体的一个简单实例如下:
 
  1. namespace testVirtualF  
  2. {  
  3.     interface BaseInterface  
  4.     {  
  5.         void doWork();  
  6.     }  
  7.     public abstract class Base:BaseInterface  
  8.     {  
  9.         public virtual void work()  
  10.         {  
  11.             Console.WriteLine("基类---现在是上班时间");  
  12.         }  
  13.         public virtual void outWork()  
  14.         {  
  15.             Console.WriteLine("基类---现在是下班时间");  
  16.         }  
  17.           
  18.         public abstract void play();//声明抽象方法,只能在抽象方法中   
  19.         public abstract void doWork();//实现接口的抽象类,可以将接口方法映射到抽象方法中   
  20.     }  
  21.   
  22.     public class Employer:Base  
  23.     {  
  24.         public  new void work()  
  25.         {  
  26.             Console.WriteLine("子类(new)---现在是上班时间");  
  27.         }  
  28.         public override void outWork()  
  29.         {  
  30.             Console.WriteLine("子类(override)---现在是下班时间");  
  31.         }  
  32.         public override void play()  
  33.         {  
  34.             Console.WriteLine("子类(override)---父类抽象方法");  
  35.         }  
  36.         public override void doWork()  
  37.         {  
  38.             Console.WriteLine("父类抽象方法--doWork");  
  39.         }  
  40.     }  
  41.     class Program  
  42.     {  
  43.         static void Main(string[] args)  
  44.         {  
  45.             /*Employer emp = new Employer(); 
  46.             emp.work(); 
  47.             emp.outWork(); 
  48.             emp.play();*/  
  49.             /*输出结果 
  50.              * 子类(new)---现在是上班时间 
  51.              * 子类(override)---现在是下班时间 
  52.              */  
  53.   
  54.             /*Employer emp = new Employer(); 
  55.             Base b = (Base)emp; 
  56.             //b.ID = "123"; 
  57.             b.work(); 
  58.             b.outWork(); 
  59.             b.play();*/  
  60.             /*执行结果 
  61.              * 基类---现在是上班时间 
  62.              * 子类(new)---现在是上班时间 
  63.              * 子类(override)---现在是下班时间 
  64.              */  
  65.   
  66.             Base b = new Employer();  
  67.             b.work();  
  68.             b.outWork();  
  69.             b.play();  
  70.             /*执行结果 
  71.              * 基类---现在是上班时间 
  72.              * 子类(new)---现在是上班时间 
  73.              * 子类(override)---现在是下班时间 
  74.              */  
  75.         }  
  76.     }  
  77. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多