C#关键字扫盲——Virtual 虚拟

Virtual

virtual
官方描述:关键字用于修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。

配合的关键字

override
官方描述:扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现需要 override 修饰符。

new
修饰符 官方描述:在用作声明修饰符时,new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本。 虽然可以不使用 new 修饰符来隐藏成员,但将收到编译器警告。 如果使用 new 来显式隐藏成员,将禁止此警告。(new有很多用途,这里主要用作于修饰符)


项目源码地址:https://gitee.com/michel4liu/LearnCSharp.git
项目:LearnVirtual
环境VS2017 .NET Core2.0


virtual+override 比较常见的用法

    static void Main(string[] args)
    {
            Father f = new Father();
            f.DoSomething();//输出 Father.Work

            Son s = new Son();
            s.DoSomething();//输出 Son.Learn

            Father fs = new Son();
            fs.DoSomething();//输出 Son.Learn
    }

    class Father
    {
        public virtual void DoSomething()
        {
            Console.WriteLine($"{nameof(Father)}.Work");
        }
    }

    class Son : Father
    {
        public override void DoSomething()
        {
            Console.WriteLine($"{nameof(Son)}.Learn");
        }
    }

重点在于第三个输出
Father fs = new Son();
fs.DoSomething(); //输出 Son.Learn
因 Son 利用关键字 override 重写 DoSomething() 所以用Father声明接收时也能指向Son.DoSomething()

virtual+New

    static void Main(string[] args)
    {
            Father f = new Father();
            f.DoSomething();//输出 Father.Work

            Son s = new Son();
            s.DoSomething();//输出 Son.Learn

            Father fs = new Son();
            fs.DoSomething();//输出 Father.Learn
    }

    class Father
    {
        public virtual void DoSomething()
        {
            Console.WriteLine($"{nameof(Father)}.Work");
        }
    }

    class Son : Father
    {
        public new void DoSomething()
        {
            Console.WriteLine($"{nameof(Son)}.Learn");
        }
    }

重点在于第三个输出
Father fs = new Son();
fs.DoSomething(); //输出 Son.Learn
因 Son 利用关键字 new 隐藏继承DoSomething() 所以用Father声明接收Son对象时只能指向Father.DoSomething()


注意点

  1. 如果Father和Son 中都不指定virtual、override 、new 关键字,编译默认使用new,编译器会报警告。
  2. New和Override 关键字互斥的。不可以同时使用。
  3. New重写后能通过转换(如获取父对象调用或base.方法())找到基类的方法,Override 重写后则无法找到基类方法。

猜你喜欢

转载自blog.csdn.net/michel4liu/article/details/79605409