• virtual、override、sealed、abstract怎么用?


    virtual { 有方法体 }

    abstract {不能有方法体}

     C#的方法引入了virtual、override、sealed、abstract四种修饰符来提供不同的继承需求。类的虚方法是可以在该类的继承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

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

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

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

    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”);

        }

    }

    抽象方法可以抽象一个继承来的虚方法。抓住了运行时绑定和编译时绑定的基本机理,便能看透方法呈现出的overload、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 可以看到类Child中F()方法的声明采取了重写(new)来屏蔽父类中的非虚方法F()的声明,而G()方法采用了覆盖(override)来提供方法的多态机制。需要注意的是重写(new)方法和覆盖(override)的不同,从本质上讲重写方法是编译时绑定,而覆盖方法是运行时绑定。值得指出的是虚方法不可以是静态方法——也就是说不可以用static和virtual同时修饰一个方法,这是由它的运行时类型辨析机制所决定的。override必须和virtual配合使用,当然也就不能和static同时使用。 如果在一个类的继承体系中不想再使一个虚方法被覆盖,该怎样做呢?答案是sealed override(密封覆盖),用sealed和override同时修饰一个虚方法便可以达到这种目的: sealed override public void F()。注意这里一定是sealed和override同时使用,也一定是密封覆盖一个虚方法,或者一个被覆盖(而不是密封覆盖)了的虚方法。密封一个非虚方法是没有意义的,也是错误的。 抽象(abstract)方法在逻辑上类似于虚方法,只是不能像虚方法那样被调用,是一个接口的声明而非实现。抽象方法没有方法实现,也不允许这样做。抽象方法同样不能是静态的。含有抽象方法的类一定是抽象类,也一定要加abstract类修饰符。但抽象类并不一定要含有抽象方法。继承含有抽象方法的抽象类的子类必须覆盖并实现(直接使用override)该方法,或者组合使用abstract override使之继续抽象,或者不提供任何覆盖和实现,后两者的行为是一样的。看下面的例子: 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”);} } 抽象方法可以抽象一个继承来的虚方法。抓住了运行时绑定和编译时绑定的基本机理,便能看透方法呈现出的overload、virtual、override、sealed、abstract等形态

  • 相关阅读:
    Moinmoin wiki 中文附件名的解决办法
    TFS2012 服务器安装
    利用openssl自建CA体系
    latex 添加Bibtex 全解(使用TeXstudio)
    BlockStack常见词语
    量子计算和量子信息: 读书笔记
    Vue 中的keep-alive 什么用处?
    打包vue文件,上传到服务器
    修改vscode的文件,对应的磁盘文件不改变
    html5的 history模式和hash模式
  • 原文地址:https://www.cnblogs.com/lori/p/1688179.html
Copyright © 2020-2023  润新知