关于虚方法virtual和抽象方法以及多态的研究

原创 2015年11月21日 19:27:23

虚方法virtual定义:    

当类中的方法声明前加上了virtual   修饰符,我们称之为虚方法,反之为非虚。使用了virtual   修饰符后,不允许再有static,   abstract,   或override 修饰符(必须是Public)。   为了实现多态,父类里面的方法用虚方法,子类里面可以对该方法重写,也可以不重写,当我们创建了一个子类 的对象并把它转换成了父类的类型后,如果子类里面没有重写父类里面的虚方法,则直接调用父类的方法,如果子类 里面重写了虚方法,则调用子类时面重写后的方法。

虚方法和非虚方法什么区别呢?

对于非虚的方法,无论被其所在类的实例调用,还是被这个类的派生类的实例调用,方法的执行方式不变对于虚方法它的执行方式可以被派生类改变,这种改变是通过方法的重载来实现的。举个例子(简单的代码):

 class A
 2     {
 3         public void F() { Console.WriteLine("A.F"); }
 4         public virtual void G() { Console.WriteLine("A.G"); }  //定义虚方法
 5     }
 6     class B : A
 7     {
 8         new public void F() { Console.WriteLine("B.F"); }      //这里的方法则不能重写,因为基类中的F()方法不是虚方法。
 9         public override void G() { Console.WriteLine("B.G"); }   //重写虚方法
10     }
11 static void Main(string[] args)
12         {        
18             B b = new B();
19             A a = b;      //A对象指向B对象
20             b.F();       //显示结果B.F
21             a.F();       //显示结果A.F
22             b.G();       //显示结果B.G 
23             a.G();       //显示结果B.G 实际这里调用的是不是基类中的G方法,而是派生类中重写过的G方法。
24             Console.ReadKey();
25         }
结果是:

B.F

A.F

B.G

B.G

a.G()的结果是B.G。这里了可以得出结论,当基类对象指向派生类对象时,基类的虚方法被重写,函数执行的是派生类方法。不是虚方法调用的是基类方法。

非虚拟方法的实现是不变的:无论是在声明它的类的实例上调用该方法还是在派生类的实例上调用,实现都是相同的。与此相反,虚拟方法的实现可以由派生类取代取代所继承的虚拟方法之实现的过程称为重写方法   

这里的new 是在子类对父类方法的一种替换,不写会有警告;

与抽象方法什么区别呢?

一、抽象方法的使用:
 1、方法前加abstract,同时在类前也要加abstract(必须要加),这个类称为抽象类,方法要是public。
 2、抽象方法不能实现,这里说的实现是指没有方法体,但是必须在非抽象子类里实现; 
 3、抽象方法在子类里一定要重写;
 4、任何一个非抽象子类必须要重写父类的抽象方法。
二、区别:
   1、抽象方法在父类里面一定不可以实现,即要有方法体(就是方法后面有没有大括号{ }),而虚方法在父类时面一定要带方法体;
   2、抽象方法在子类里面一定要实现,虚方法在子类里面可以不用重写,也可以重写(重写要实现)。二者都可以看做多态的范畴,这些多用在设计模式上写大型的游戏时多用在搭框架。 C#中写方法的时候,除了接口和抽象方法,其它的基本都带方法体

这两者都是多态的范畴,多态怎么理解?

  多态是我们在写方法时,为了使代码的重用性达到最大,通常都会把子类的对象转换成父类,但是在调方法时只能调到父类里面的方法,而子类里面的方法调不到,但是每个子类又有各自的行为,此时用到多态,子类时面重写父类里面的方法,,但子类在调同一个方法时,都会调到各自重写的方法,这样类型也达到了统一,处理起来也方法,同时也体现了子类 的各自的行为.(粗糙的说多态是和重写方法同时出现的,因为重写了就实现了多态,如果不重写,所有的子类调用父类的虚方法都是一样的,但是这样的话不要说出来,自己理解可以这样理解 ,说出来别人会认为你外行了。)
  另外接口也可以实现多态,多个类继承一个接口,各自类进行不同的实现后,不同的类调用接口里面的方法 ,这样也实现了多态。虚方法,抽象 方法和接口都可以实现多态,设计模式里面大多用到接口。

重写的概念:

是子类(即派生类)的方法覆盖父类(即基类)的虚方法。

   重写的要求:

1、三相同:

(1)方法名称相同

(2)参数列表相同

(3)返回值类型相同

一句话,只需重写代码体的内容!

2、重写声明不能更改虚方法的可访问性:重写方法和虚方法必须具有相同的访问级修饰符。例如:虚方法为public的,重新方法也必须是public的。

3、可以重写基方法:必须是虚拟的(virtual)、抽象的(abstract)或重写的(override)。(非虚方法或静态方法是不可以重写的)。

4、不能使用下列修饰符修改重写(override)方法(即该方法中含有override关键字):new、static、virtual、abstract

如:new public override void outwork () //这样写是不可以的

{

      MessageBox.Show("子类的子类(override)下班");

}

5、重写属性:重写的属性必须与继承属性有完全相同的访问修饰符、类型和属性名,并且重写属性必须是虚拟的(virtual)、抽象的(abstract)或是重写的(override)。

6、new关键字和override关键字比较:

        如果使用override重写xx方法,通过父类引用一样只能看到重写后的方法; override重写的是虚方法,那么就只剩下重写以后的方法,原来的方法被覆盖了。如果使用new隐藏xx方法,父类子类引用各自对应方法;new隐藏基类的方法,那么基类的方法和当前类的方法同时存在只是被隐藏了。

总结:override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已。



 



版权声明:本文为博主原创文章,未经博主允许不得转载。

虚方法(virtual)和抽象方法(abstract)的区别

 第一种解释:虚方法和抽象方法都可以供派生类重写,它们之间有什么区别呢?1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。如: ...
  • jiangxinyu
  • jiangxinyu
  • 2011年06月27日 14:49
  • 4770

虚方法【只有虚方法或者抽象方法才能被子类方法重写】

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Tes...
  • Fanbin168
  • Fanbin168
  • 2014年09月19日 16:58
  • 1546

C# 虚方法与抽象方法区别

抽象方法是只有定义、没有实际方法体的函数,它只能在抽象函数中出现,并且在子类中必须重写;虚方法则有自己的函数体,已经提供了函数实现,但是允许在子类中重写或覆盖。 重写的子类虚函数就是被覆盖了。 ...
  • snakorse
  • snakorse
  • 2015年02月17日 21:40
  • 1571

c#中抽象类和虚方法的区别?

你说的是抽象类和虚方法吧! 其实这是哲学的思维方式,所谓哲学就是建立事实基础上,是人类对世界的思考和认识。 要理解抽象类就必须要有一定的编程经验,就好像要理解哲学就需要有一定的生活经验。跟一个没有...
  • juelingfeng
  • juelingfeng
  • 2014年08月07日 13:25
  • 1328

浅谈C# 多态的魅力(虚方法,抽象,接口实现)

浅谈C# 多态的魅力(虚方法,抽象,接口实现) 前言:我们都知道面向对象的三大特性:封装,继承,多态。封装和继承对于初学者而言比较好理解,但要理解多态,尤其是深入理解,初学者往往存在...
  • huwei2003
  • huwei2003
  • 2014年02月08日 11:29
  • 13277

继承多态与虚函数及对类的理解

B是A的子类,子类会继承父类的public方法,子类对象可以调用父类的public接口,但是子类和父类函数重名时,父类的方法会被子类覆盖(隐藏),子类调用和父类同名同参函数或者重载父类的函数后不可以直...
  • qq_35956442
  • qq_35956442
  • 2016年11月17日 13:41
  • 328

虚函数、纯虚函数、抽象类、抽象方法和接口

首先讲下自己最近的电话面试遇到的相关问题。1、多态的两种实现方式?2、虚函数与纯虚函数的区别,如何使用这两种方式?3、接口和抽象类的关系?由这两个问题开始深入的理解一下虚函数,纯虚函数以及抽象类和接口...
  • feihaixin
  • feihaixin
  • 2015年02月15日 14:44
  • 710

抽象类和虚方法有什么区别

抽象方法是只有定义、没有实际方法体的函数,它只能在抽象函数中出现,并且在子类中必须重写;虚方法则有自己的函数体,已经提供了函数实现,但是允许在子类中重写或覆盖。 重写的子类虚函数就是被覆盖了。 ...
  • HurtlingSnail
  • HurtlingSnail
  • 2016年11月10日 10:51
  • 696

C#:区分:重写、覆盖和重载以及虚方法和抽象方法

(一)重写和覆盖:重写: 在声明时,父类的方法前面加上virtual关键字,子类的方法前面加上override关键字,且与父类方法同名,表示父类的方法可以被子类进行修改和重新定义。 覆盖: 在声...
  • Bambi12
  • Bambi12
  • 2017年01月16日 13:41
  • 973

虚方法&非虚方法

非虚方法:只能被invokestatic和invokespecial指令调用的方法,称为虚方法,常见的虚方法有:静态方法、私有方法、实例构造器、父类方法四种。 虚方法:除非虚方法以外的其它方法。 注意...
  • u010866364
  • u010866364
  • 2016年11月15日 09:21
  • 948
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于虚方法virtual和抽象方法以及多态的研究
举报原因:
原因补充:

(最多只允许输入30个字)