天天看点

C#中的virtual,abstract,override和new关键字

C#中virtual,abstract,override用于方法重载,子类覆盖了父类的相同方法,父类中的实现不可能再被外面调用。

new的作用是投影(shadowing),子类隐藏了父类的相同方法,通过强制类型转换外面还可以调用父类的实现。

下面是重载的例子

Code:

点击(此处)折叠或打开

class Parent

    {

        public virtual Parent foo()

        {

            System.Console.WriteLine("Parent.foo()");

            return this;

        }

    }

    class Child : Parent

        public override Parent foo()

            System.Console.WriteLine("Child.foo()");

Test:

class Program

        static void Main(string[] args)

            Child c =new Child();

            c.foo();

            ((Parent)c).foo();

Result:

Child.foo()

下面是投影的例子

        public Parent foo()

        public new Child foo()

Parent.foo()

重载的规则:

父类提供实现,则父类使用virtual关键字

父类不提供实现,则父类自身和相关方法使用abstract关键字,此时子类必须提供实现

子类重载需使用override关键字,如省略当作new(即投影)处理,并且编译器报编译警告

重载时子类方法不能改写返回值类型

子类中可以使用base关键字引用父类的实现

投影的规则:

父类必须提供实现(甚至可以有virtual关键字)

子类应该使用new关键字,如省略也当作new处理,但编译器报编译警告

投影时子类方法可以改写返回值类型

除此以外还有一种接口投影的情况,通过接口投影可以新定义一个和接口定义同名同参但不同返回类型的函数。

比如:

interface MyInterface

        Object foo();

    class MyImp : MyInterface

        Object MyInterface.foo()

            System.Console.WriteLine("MyInterface.foo()");

            return null;

        public MyImp foo()

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

MyImp myImp = new MyImp();

    myImp.foo();

    ((MyInterface)myImp).foo();

foo()

MyInterface.foo()