当前位置:文档之家› 虚方法和重写方法

虚方法和重写方法


类ANew用关键字new重新定义了一个和基类同名函 数,类AOverride 用override覆盖了基类的同名函数, 那么区别就出来了: 1.使用ANew,AOverride 的对象调用函数print,当然 出现的是他们类体内的函数 ANew anew = new ANew(); AOverride aover = new AOverride(); anew.print();//---------》Console.WriteLine("类 ANew的函数"); aover.print();//--------》 Console.WriteLine(" 类AOverride的函数");
虚方法的定义形式
virtual 修饰符 返回的数据类型 方法名(参数表) { 方法体 }
对于非虚的方法,无论被其所在类的实例调用, 还是被这个类的派生类的实例调用,方法的执 行方式不变。而对于虚方法,它的执行 方式可以被派生类改变,这种改变是通过方法 的重载来实现的。
虚方法的重载形式
override 修饰符 返回的数据类型 方法名(参数表) { 方法体 } override 重写继承自基类的 virtural 方法,可以 理解为拆掉老房子,在原址上建新房子,老房子再也 找不到了(基类方法永远调用不到了)。
注意
只有类才有析构函数,结构是没有析构函数的, 并且每个类最多只能有一个析构函数。析构函 数不能被继承、不能重载、不能被外部程序显 示调用。
using System; class Decon1 { public Decon1( ) { Console.WriteLine(“调用构造函数 调用构造函数Decon1”); 调用构造函数 } ~Decon1( ) { Console.WriteLine(“调用析构函数 调用析构函数Decon1”); 调用析构函数 } } class Decon2 { public Decon2( ) { Console.WriteLine(“调用构造函数 调用构造函数Decon2”); 调用构造函数 } ~Decon2( ) { Console.WriteLine(“调用析构函数 调用析构函数Decon2”); 调用析构函数 } } class Test { public static void Main() { Decon1 dec1=new Decon1( ); Decon2 dec2=new Decon2( ); } }
析构函数
当某个对象用完后,要将其从内存中清除前, 当某个对象用完后,要将其从内存中清除前,必须释放它所占用 的内存,这时就需要用到类的析构函数。 的内存,这时就需要用到类的析构函数。 定义析构函数与定义构造函数非常相似, 定义析构函数与定义构造函数非常相似,析构函数的名称是在 类名前加一个“ 符号 符号。 类名前加一个“~”符号。 格式: 格式: class 类名 { …… ~类名 ) 类名( 类名 { //析构函数体 析构函数体 } } 注意:如果类没有析构函数, 注意:如果类没有析构函数,系统就自动调用默认的析构函数来 完成内存的回收。在实际编程过程中,一般不需要析构函数。 完成内存的回收。在实际编程过程中,一般不需要析构函数。 析构函数以与构造函数相反的顺序被调用。 析构函数以与构造函数相反的顺序被调用。
using System; class A { public void F(){Console.WriteLine("A.F");} public virtual void G(){Console.WriteLine("A.G");} } class B:A { new public void F(){Console.WriteLine("B.F");} public override void G(){Console.WriteLine("B.G");} } class Tese { static void Main(){ B b=new B(); A a=b; a.F(); b.F(); a.G(); b.G(); } }
虚方法和重写方法
虚方法
当类中的方法声明前加上了virtual修饰符, 我们称之为虚方法,反之为非虚。使用了 virtual修饰符后,不允许再有 static,abstract,或override修饰符。 若希望或预料到基类的这个方法在将来的 派生类中会被重写( ),则此方法 派生类中会被重写(override ),则此方法 必须被声明为 virtual。 。
例子
class A { public virtual void print() { Console.WriteLine("类A的函数 的函数"); 类 的函数 } } class ANew:A { public new void print() { Console.WriteLine("类ANew的函数 的函数"); 类 的函数 } } class AOverride : A { public override void print() { Console.WriteLine("类AOverride的函数 的函数"); 类 的函数 } }
New和overde的相同点: 的相同点: 和 的相同点 * 都可以对基类成员进行隐藏,都可以用 都可以对基类成员进行隐藏,都可以用base关键字 关键字 调用基类的成员 * new和override的不同点: 的不同点: 和 的不同点 * 用override的基类的方法必须要用 的基类的方法必须要用virtual,而new 的基类的方法必须要用 , 不必要 * 本质区别在于当派生类对象作为基类类型使用时, 本质区别在于当派生类对象作为基类类型使用时, override 的执行派生类方法,new 的执行基类方法。 的执行派生类方法, 的执行基类方法。 如果作为派生类类型调用, 如果作为派生类类型调用,则都是执行 override 或 new 之后的。 之后的。
override 重写继承自基类的 virtural 方法,可以理解 为拆掉老房子,在原址上建新房子,老房子再也找不 到了(基类方法永远调用不到了)。 new 隐藏继承自基类的 virtual 方法,老房子还留着, 在旁边盖个新房,想住新房住新房(作为派生类对象 调用),想住老房住老房(作为基类对象调用)。 当派生类中出现与基类同名的方法,而此方法前面 未加 override 或 new 修饰符时,编译器会报警告, 但不报错,真正执行时等同于加了 new。
2. 当使用基类的对象引用来调用print函数时,就出现 了差别 A[] Aarr = new A[2]; ANew anew = new ANew(); AOverride aover = new AOverride(); Aarr[0] = anew; Aarr[1] = aover; Aarr[0].print();//--------》Console.WriteLine(" 类A的函数"); Aarr[1].print();//--------》Console.WriteLine(" 类AOverride的函数");
相关主题