您现在的位置是: 软件 > 开发者网络 > 微软开发专栏 > Visual Studio.net专栏 > C#专区 > 正文


-网页表格制作速查手册
-Visual C++ MFC/ATL开发
-Visual C++ 数据库开发
-打开闪烁的新世界:体验Flash MX

C#锐利体验(六)
2002-04-12· ·李建忠··Microsoft

上一页  1 2 3 4  下一页

  方法继承

  第一等的面向对象机制为C#的方法引入了virtual,override,sealed,abstract四种修饰符来提供不同的继承需求。类的虚方法是可以在该类的继承自类中改变其实现的方法,当然这种改变仅限于方法体的改变,而非方法头(方法声明)的改变。被子类改变的虚方法必须在方法头加上override来表示。当一个虚方法被调用时,该类的实例--亦即对象的运行时类型(run-time type)来决定哪个方法体被调用。我们看下面的例子:

using System;
class Parent
{
    public void F() { Console.WriteLine("Parent.F"); }
    public virtual void G() { Console.WriteLine("Parent.G"); }
}
class Child: Parent
{
    new public void F() { Console.WriteLine("Child.F"); }
    public override void G() { Console.WriteLine("Child.G"); }
}
class Test
{
    static void Main()
    {
        Child b = new Child();
        Parent a = b;
        a.F();
        b.F();
        a.G();
        b.G();
    }
}

  程序经编译后执行输出:

Parent.F
Child.F
Child.G
Child.G

  我们可以看到class Child中F()方法的声明采取了重写(new)的办法来屏蔽class Parent中的非虚方法F()的声明。而G()方法就采用了覆盖(override)的办法来提供方法的多态机制。需要注意的是重写(new)方法和覆盖(override)方法的不同,从本质上讲重写方法是编译时绑定,而覆盖方法是运行时绑定。值得指出的是虚方法不可以是静态方法--也就是说不可以用static和virtual同时修饰一个方法,这由它的运行时类型辨析机制所决定。override必须和virtual配合使用,当然也不能和static同时使用。

  那么我们如果在一个类的继承体系中不想再使一个虚方法被覆盖,我们该怎样做呢?答案是sealed override (密封覆盖),我们将sealed和override同时修饰一个虚方法便可以达到这种目的:sealed override public void F()。注意这里一定是sealed和override同时使用,也一定是密封覆盖一个虚方法,或者一个被覆盖(而不是密封覆盖)了的虚方法。密封一个非虚方法是没有意义的,也是错误的。看下面的例子:

//sealed.cs
// csc /t:library sealed.cs
using System;
class Parent
{
    public virtual void F()
    {
        Console.WriteLine("Parent.F");
    }
    public virtual void G()
    {
        Console.WriteLine("Parent.G");
    }
}
class Child: Parent
{
    sealed override public void F()
    {
        Console.WriteLine("Child.F");
    }
    override public void G()
    {
        Console.WriteLine("Child.G");
    }
}
class Grandson: Child
{
    override public void G()
    {
        Console.WriteLine("Grandson.G");
    }
}

  抽象(abstract)方法在逻辑上类似于虚方法,只是不能像虚方法那样被调用,而只是一个接口的声明而非实现。抽象方法没有类似于{…}这样的方法实现,也不允许这样做。抽象方法同样不能是静态的。含有抽象方法的类一定是抽象类,也一定要加abstract类修饰符。但抽象类并不一定要含有抽象方法。继承含有抽象方法的抽象类的子类必须覆盖并实现(直接使用override)该方法,或者组合使用abstract override使之继续抽象,或者不提供任何覆盖和实现。后两者的行为是一样的。看下面的例子:

//abstract1.cs
// csc /t:library abstract1.cs
using System;
abstract class Parent
{
    public abstract void F();

    public abstract void G();
}
abstract class Child: Parent
{
    public abstract override void F();
}
abstract class Grandson: Child
{
    public override void F()
    {
        Console.WriteLine("Grandson.F");
    }
    public override void G()
    {
        Console.WriteLine("Grandson.G");
    }
}

  抽象方法可以抽象一个继承来的虚方法,我们看下面的例子:

//abstract2.cs
// csc /t:library abstract2.cs
using System;
class Parent
{
    public virtual void Method()
    {
        Console.WriteLine("Parent.Method");
    }
}
abstract class Child: Parent
{
    public abstract override void Method();
}
abstract class Grandson: Child
{
    public override void Method()
    {
        Console.WriteLine("Grandson.Method");
    }
}

  归根结底,我们抓住了运行时绑定和编译时绑定的基本机理,我们便能看透方法呈现出的种种overload,virtual,override,sealed,abstract等形态,我们才能运用好方法这一利器!

上一页  1 2 3 4  下一页

■ 相关内容
 锋利的新语言:C#提供了C++的功能和Visual Basic的简单性
 DirectDraw之C#入门攻略
 使用C#轻松编写.Net组件
 使用C#开发一个简单的P2P应用
 Visual C# 对话框全接触
 从C/C++到C#的锐利之路
 C#中调用API
 在C#中使用微软AGENT之TTS
 C#与Java述评
 C#的多线程机制探索
感谢 访问天极网,如果您觉得该文章涉及版权问题,请看这里!