abstract、virtual、override 和 new(转载)

上一篇 / 下一篇  2009-05-27 14:34:34

 

作者:阳春三月

   abstract、virtual、override 和 new 是在类的继承关系中常用的四个修饰方法的关键字,在此略作总结。

1. 常用的中文名:abstract 抽象方法,virtual 虚方法,override 覆盖基类方法,new 隐藏基类方法,override 和 new 有时都叫重写基类方法。

2. 适用场合:abstract 和 virtual 用在基类(父类)中;override 和 new 用在派生类(子类)中。

3. 具体概念:

    abstract 抽象方法,是空方法,没有方法体,派生类必须以 override 实现此方法。

    virtual 虚方法,若希望或预料到基类的这个方法在将来的派生类中会被重写(override 或 new),则此方法必须被声明为 virtual。

    override 重写继承自基类的 virtural 方法,可以理解为拆掉老房子,在原址上建新房子,老房子再也找不到了(基类方法永远调用不到了)。

    new 隐藏继承自基类的 virtual 方法,老房子还留着,在旁边盖个新房,想住新房住新房(作为派生类对象调用),想住老房住老房(作为基类对象调用)。

    当派生类中出现与基类同名的方法,而此方法前面未加 override 或 new 修饰符时,编译器会报警告,但不报错,真正执行时等同于加了 new。

4. abstract 和 virtual 的区别:abstract 方法还没实现,连累着基类也不能被实例化,除了作为一种规则或符号外没啥用;virtual 则比较好,派生类想重写就重写,不想重写就吃老子的。而且继承再好也是少用为妙,继承层次越少越好,派生类新扩展的功能越少越好,virtual 深合此意。

5. override 和 new 的区别:当派生类对象作为基类类型使用时,override 的执行派生类方法,new 的执行基类方法。如果作为派生类类型调用,则都是执行 override 或 new 之后的。


演示 override 和 new 区别的例子:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication1

{

class Program

{

class Car

{

public virtual void D()

{

Console.WriteLine("base");

}

}

class ConvertibalCar : Car

{

public new void D()

{

base.D();

Console.WriteLine("convertibalcar");

}

}

class Minivan : Car

{

public override void D()

{

base.D();

Console.WriteLine("Minivan");

}

}

static void Main(string[] args)

{

Car car1 = new Car();

car1.D();

Console.WriteLine("0000000000000");

ConvertibalCar car2 = new ConvertibalCar();

car2.D();

Console.WriteLine("000000000000");

Minivan car3 = new Minivan();

car3.D();

}

}

}

 

输出类似如下所示:

Four wheels and an engine.

----------

Four wheels and an engine.

A roof that opens up.

----------

Four wheels and an engine.

Carries seven people.

----------

但是,如果我们声明一个从 Car 基类派生的对象的数组。此数组能够存储 Car、ConvertibleCar 和 Minivan 对象,如下所示:


public static void TestCars2()
{
    Car[] cars 
= new Car[3];
    cars[
0= new Car();
    cars[
1= new ConvertibleCar();

    cars[2] = new Minivan();

}

 

然后用一个 foreach 循环来访问该数组中包含的每个 Car 对象,并调用 DescribeCar 方法,如下所示:


foreach (Car vehicle in cars)
{
  System.Console.WriteLine(
"Car object: " + vehicle.GetType());
  vehicle.DescribeCar();

  System.Console.WriteLine("----------");

}

 

此循环的输出如下所示:

Car object: YourApplication.Car

Four wheels and an engine.

----------

Car object: YourApplication.ConvertibleCar

Four wheels and an engine.

----------

Car object: YourApplication.Minivan

Four wheels and an engine.

Carries seven people.

----------

注意,ConvertibleCar 的说明可能与您的预期不同。由于使用了 new 关键字来定义此方法,所调用的不是派生类方法,而是基类方法。Minivan 对象正确地调用重写方法,并产生预期的结果。

 

TAG: 开发

 

评分:0

我来说两句

日历

« 2024-03-27  
     12
3456789
10111213141516
17181920212223
24252627282930
31      

数据统计

  • 访问量: 6788
  • 日志数: 14
  • 建立时间: 2009-01-06
  • 更新时间: 2010-07-11

RSS订阅

Open Toolbar