小新的技术天地

Make It Works !

博客园 首页 新随笔 联系 订阅 管理
不使用virtual,你仍然可以在派生类中是相同的信号和返回类型编写函数。

请看代码:
using System;

class Car
{
    
public virtual void MoveForward()
    
{
        Console.WriteLine(
"Move Car forward by 1 kilometer");
    }

    
    
public void Reverse()
    
{
        Console.WriteLine(
"Reverse Car by 50 meters");
    }

}


class FamilyCar : Car
{
    
public override void MoveForward()
    
{
        Console.WriteLine(
"Move Family Car forward by 5 kilometers"); 
    }

    
    
public new void Reverse()
    
{
        Console.WriteLine(
"Reverse the Family Car by 200 meters");
    }

}


class Tester
{
    
public static void Main()
    
{
        Car myCar;
        
        myCar 
= new FamilyCar();
        myCar.MoveForward();
        myCar.Reverse();
        
        Console.ReadLine();
    }

}

我们可以看到一个基类Car和一个派生类FamilyCar

基类中有两个方法MoveForward()和Reverse(),一个为虚方法,另一个为非虚方法,然后在派生类中,MoveForward被覆盖(override)了,而Reverse使用了关键字new,这个new跟我们实例化新对象的new含义不同。我们在这暂时不讨论,暂时就认为包含关键字是为了避免编译器发出警告。(我试了一下,如果不写new关键字,会有如下警告:
“warning CS0108: “FamilyCar.Reverse()”上要求关键字 new,因为它隐藏了继承成员“Car.Reverse()”)

编译结果为:
Move Family Car forward by 5 kilometers
Reverse Car by 50 meters

这说明对虚方法MoveForward()使用了动态捆绑技术,所以执行了派生类中的实现语句。而对非虚方法Reverse()没有使用动态捆绑技术,所以执行了基类中的实现语句。

那么我们要让myCar引用一个派生类对象,而我们要执行派生类的Reverse方法,该怎么办呢?那么我们就需要为Reverse方法声明为virtual,也就是跟MoveForward一样。(这里原文在语意上有一点问题,如果把基类中Reverse方法声明为virtual,而派生类中还是用new关键字,那么结果跟上面的结果是一样的,并没有满足我们的要求,其实原作者的言下之意是派生类中也跟MoveForward一样,使用override关键字)

大部分基类声明的函数都需要声明为virtual以避免上面的非虚方法Reverse所导致的问题。那么虚方法用的多,为什么不带virtual关键字的函数缺省时为非虚方法呢?且待下回说明:)

注:此文参考《C# Primer Plus 中文版》
posted on 2004-11-18 19:28  小新0574  阅读(1112)  评论(3编辑  收藏  举报