关于虚方法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不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已。



 



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

相关文章推荐

var 匿名类型 父类使用子类的方法 虚方法 this和 base

猴子双野不猴子双野不猴子双野不    引入其他猴子双野不项目的类的方法。在VS的 类视图中右键 》添加引用选择要引用的项目,然后再类中添加using;   如果使用父类来初始化enemy 是无法强制转...

[脚本] C#虚函数在UNITY3D里的应用

using UnityEngine; using System.Collections; using System; public class A {    public virtual vo...

虚方法与抽象方法有什么区别

虚方法与抽象方法有什么区别 抽象方法是只有定义、没有实际方法体的函数,它只能在抽象函数中出现,并且在子类中必须重写;虚方法则有自己的函数体,已经提供了函数实现,但是允许在子类中重写或覆盖。 重写的子...
  • wm9901
  • wm9901
  • 2015年04月07日 22:08
  • 892

网友对spring.net的理解:(为什么要用晦涩难懂的spring?)

1、你在学习的时候就那点代码量,随便在Action中new一new 无所谓,当你的项目很大的时候,代码一多你每个Action再去new DAO的时候你就知道有多么痛苦的,而且你每new一次就给你产生一...

spring依赖注入的好处以及三种注入的方式

spring依赖注入的好处 依赖注入框架——其实就是在使用类似反射的机制!!不让对象 new 出来,就降低了依赖! 这些大型框架除了 所谓的“依赖注入”之外,还有 调用拦截(AOP)! 那些...

使用抽象方法实现多态

  • 2009年04月22日 17:02
  • 66KB
  • 下载

黑马程序员_多态、抽象方法、虚方法

1.多态:即是多种形态;
  • aipeng
  • aipeng
  • 2014年07月21日 22:06
  • 414

虚方法和抽象方法以及多态的本质(里氏替换原则)!

函数重写:被重写的父类函数必须是【虚方法或抽象方法】 函数必须相同(返回值、函数名、参数列表) 重写的函数的修饰符必须等于父类 重写的函数的返回值类型等于父类返回值 构造函数无法重写(因为构造...

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

 第一种解释:虚方法和抽象方法都可以供派生类重写,它们之间有什么区别呢?1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。如: ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于虚方法virtual和抽象方法以及多态的研究
举报原因:
原因补充:

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