• abstract、override、new、virtual、sealed使用和示例


    abstract修饰类名为抽象类,修饰方法为抽象方法。如果一个类为抽象类,则这个类智能是其他某个类的基类。抽象方法在抽象类中没有函数体。抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法。

    抽象类有如下特征:

            抽象类不能实例化

            抽象类的派生类必须实现所有抽象方法

            抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽象方法

    抽象方法:

            抽象方法是隐式的虚方法

            只允许在抽象类中使用抽象方法声明

            抽象方法在抽象类中没有方法体

            在抽象方法声明中,不能使用static或者virtual修饰符

    abstract class A //abstract 关键字在class前面

    {

        public abstract void run();//方法是将关键字abstract 添加到方法的返回类型的前面

    }

     

    override关键字提供派生类对基类方法的新的实现,重写的基类方法必须和基类的方法有着相同的签名(函数名、返回值、参数列表相同)。

    override关键字不可以重写基类非virtual修饰的方法和static修饰的静态方法。

    派生类的override方法和基类的virtual方法必须有相同的访问权限。不能用修饰符new、static、virtual或者abstract修饰override方法。

    派生类的override方法重写的基类方法必须是virtual、abstract或者override的。

    abstract class A

    {

    public virtual void MethodA()

    {

         //do something

    }

    public abstract void run();

    }

         public class B:A

    {

    public override void MethodA()

    {

        //do somthing

    }

    public virtual void run()

    {

        //do something

    }

    }

    new 

    c#中,new的关键字主要有三个功能:

         作为运算符用来创建类的一个对象。 Class obj = new Class();

         作为修饰符。

         用于在泛型声明中约束可能用作类型参数的参数类型。(这个不太清楚)

     

    在这里主要介绍第2个功能,作为修饰符的作用。

         new声明的方法,当使用子类的类型来调用的时候,它会运行子类的函数,而如果类型是基类的话,被隐藏的基类函数会被调用。

         而子类中函数使用override的时候,则当使用子类的类型来调用的是,它会运行子类的函数,类型是基类的时候,仍会调用子类函数。

      // Define the base class

        class Car

        {

            public virtual void DescribeCar()

            {

                System.Console.WriteLine("Four wheels and an engine.");

            }

        }

        // Define the derived classes

        class ConvertibleCar : Car

        {

            public new void DescribeCar()

            {

                System.Console.WriteLine("A roof that opens up.");

            }

        }

        class Minivan : Car

        {

            public override void DescribeCar()

            {

                System.Console.WriteLine("Carries seven people.");

            }

        }

        public class Program

        {

            public static void Main()

            {

                Car car1 = new Car();

                car1.DescribeCar();

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

     

     

                Car car2 = new ConvertibleCar();

                car2.DescribeCar();

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

                Car car3 = new Minivan();

                car3.DescribeCar();

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

                System.Console.ReadKey();

            }

        }

     

    Virtual

    virtual 关键字允许在派生类中重写这些对象。默认情况下,方法是非虚拟的,不可以重写非虚方法,virtual关键字不可以与static、abstract、private、override一起使用。virtual关键字又是和override紧密不可分的,如果要实现virtual方法就必须要使用override或new关键字(上文已经指出new和override产生的机理不同)。

    Sealed

       当对一个类应用sealed修饰符时,此修饰符会阻止其他类从该类继承。

          sealed 方法必须与override连用,也就是说实现sealed方法的类的父类必须实现了此方法。      sealed关键字有两个作用:

         1 密封类不能被继承。

         2 密封方法重写基类中的方法,但其本身不能在任何派生类中进一步重写

    sealed实例:

    class X

     

        {

            protected virtual void F() { Console.WriteLine("X.F"); }

            protected virtual void F2() { Console.WriteLine("X.F2"); }

        }

        class Y : X

        {

            sealed protected override void F() { Console.WriteLine("Y.F"); }

            protected override void F2() { Console.WriteLine("X.F3"); }

        }

        class Z : Y

        {

            // Attempting to override F causes compiler error CS0239.

            // protected override void F() { Console.WriteLine("C.F"); }//sealed修饰的方法是不允许继承的

     

            // Overriding F2 is allowed.

            protected override void F2() { Console.WriteLine("Z.F2"); }

        }

     

     

    整体的一个简单实例如下:

    namespace testVirtualF

    {

        interface BaseInterface

        {

            void doWork();

        }

        public abstract class Base:BaseInterface

        {

            public virtual void work()

            {

                Console.WriteLine("基类---现在是上班时间");

            }

            public virtual void outWork()

            {

                Console.WriteLine("基类---现在是下班时间");

            }

            

            public abstract void play();//声明抽象方法,只能在抽象方法中

            public abstract void doWork();//实现接口的抽象类,可以将接口方法映射到抽象方法中

        }

     

        public class Employer:Base

        {

            public  new void work()

            {

                Console.WriteLine("子类(new)---现在是上班时间");

            }

            public override void outWork()

            {

                Console.WriteLine("子类(override)---现在是下班时间");

            }

            public override void play()

            {

                Console.WriteLine("子类(override)---父类抽象方法");

            }

            public override void doWork()

            {

                Console.WriteLine("父类抽象方法--doWork");

            }

        }

        class Program

        {

            static void Main(string[] args)

            {

                /*Employer emp = new Employer();

                emp.work();

                emp.outWork();

                emp.play();*/

                /*输出结果

                 * 子类(new)---现在是上班时间

                 * 子类(override)---现在是下班时间

                 */

     

                /*Employer emp = new Employer();

                Base b = (Base)emp;

                //b.ID = "123";

                b.work();

                b.outWork();

                b.play();*/

                /*执行结果

                 * 基类---现在是上班时间

                 * 子类(new)---现在是上班时间

                 * 子类(override)---现在是下班时间

                 */

     

                Base b = new Employer();

                b.work();

                b.outWork();

                b.play();

                /*执行结果

                 * 基类---现在是上班时间

                 * 子类(new)---现在是上班时间

                 * 子类(override)---现在是下班时间

                 */

            }

        }

    }

  • 相关阅读:
    19.2.8 [LeetCode 53] Maximum Subarray
    19.2.8 [LeetCode 52] N-Queens II
    19.2.8 [LeetCode 51] N-Queens
    19.2.7 [LeetCode 50] Pow(x, n)
    19.2.7 [LeetCode 49] Group Anagrams
    19.2.7 [LeetCode 48] Rotate Image
    19.2.7 [LeetCode 47] Permutations II
    19.2.7 [LeetCode 46] Permutations
    19.2.7 [LeetCode 45] Jump Game II
    19.2.4 [LeetCode 44] Wildcard Matching
  • 原文地址:https://www.cnblogs.com/wlming/p/5160526.html
Copyright © 2020-2023  润新知