C#浅析 virtual、abstract、interface、override\new

 

【虚方法】

virtual关键字用于在基类中修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象。

virtual的使用会有两种情况:
 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。
 情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。

 

【抽象方法】

 abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现,请务必将抽象方法放在抽象类中。
 非抽象类的派生类必须全部实现父类的抽象方法和抽象访问器,使用override关键字来实现。

 

【接口】

 接口用于描述一组类的公共方法/公共属性
 接口中的方法没有具体实现,也就是没有方法体,必须由继承者去实现而且必须全部实现。
 接口中的方法不需要修饰符,默认就是公有的
 接口可以包含方法、属性、索引器、事件。不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员

 

【虚方法 VS 抽象方法】

虚方法和抽象方法都可以供派生类重写
 1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化;而虚方法提供了选择,可以覆盖可以不覆盖。
 2. 抽象方法只能在抽象类中声明,虚方法不是。

 

【抽象 VS 接口】

 抽象类和接口都不能实例化
 抽象类可以包含非抽象方法,而接口只能包含抽象方法
 一个类可以实现多接口,单继承

 

 1 class Father
 2     {
 3         public void F() { Console.WriteLine("A.F"); }
 4         public virtual void G() { Console.WriteLine("A.G"); }
 5     }
 6     class Son : Father
 7     {
 8         new public void F() { Console.WriteLine("B.F"); }//new 隐藏了父类中的方法,父类中的F方法还存在
 9         public override void G() { Console.WriteLine("B.G"); }//override 重写了父类中的方法,父类中的G方法就不存在了
10     }
11     class override_new
12     {
13         static void Main()
14         {
15             Son b = new Son();
16             Father a = b;
17             a.F();//通过父类声明的对象 调用隐藏方法,会调用父类中的  A.F
18             b.F();//通过子类声明的对象 调用隐藏方法,会调用子类中的  B.F
19             a.G();// B.G    //若Son中是 new void G(),则结果为 A.G
20             b.G();//B.G
21         }
22     } //输出 A.F B.F B.G B.G

 

 

 1     public class A
 2     {
 3         public virtual void Fun1(int i)
 4         {
 5             Console.WriteLine(i);
 6         }
 7         public void Fun2(A a)
 8         {
 9             a.Fun1(1);
10             Fun1(5);
11         }
12     }
13     public class B : A
14     {
15         public override void Fun1(int i)
16         {
17             base.Fun1(i + 1);
18         }
19         public static void Main()
20         {
21             B b = new B();
22             A a = new A();
23             a.Fun2(b);//b.Fun1(1) a.Fun1(5) //2  5
24             b.Fun2(a);//a.Fun1(1) b.Fun1(5)// 1   6
25         }
26     }  //输出 2 5 1 6

 

posted @ 2017-03-12 09:54  LetitiaChan  阅读(245)  评论(0编辑  收藏  举报