您的位置:首页 > 编程语言 > C#

有关C#关键字new、override、virtual的总结

2015-05-25 20:14 357 查看
这篇文章摘抄总结自:

1.张令

2.祥叔学编程

3.MSDN

先看一个例子:

class Program
    {
        static void Main(string[] args)
        {
            contact ct1 = new class1();
            contact ct2 = new class2();
            ct1.prinf();
            ct2.prinf();
        }
    }
    abstract public class contact
    {
        public virtual void prinf()    //关键字virtual
        {
            Console.WriteLine("这是虚方法");
        }

    }
    public class class1 : contact
    {
        public override void prinf()   //关键字override
        {
            Console.WriteLine("这是新的方法");
        }

    }

    public class class2 : contact
    {
        public new void prinf()     //关键字new
        {
            Console.WriteLine("这是另一个新的方法");
        }

    }


简单的看到了override和new(不写new,或者override 默认为隐性的调用new)的区别

在这里就是override和virtual可以执行多态,而new关键字显示的指明不能实行多态(感觉就是比C++多了一个关键

字)

再看第二组例子:

class Program
    {
        static void Main(string[] args)
        {
            C1 c1 = new C1();
            Console.WriteLine(c1.GetName());//输出“祥叔”

            C2 c2 = new C2();
            Console.WriteLine(c2.GetName());//输出“xiangshu”

            //重点看这里

            C1 c3 = new C2();
            Console.WriteLine(c3.GetName());//输出“xiangshu” 
        }
    }
    public class C1
    {
        public virtual string GetName()
        {
            return "叔祥";
        }
    }

    public class C2 : C1
    {
        public override string GetName()
        {
            return "xiangshu";
        }
    }


class Program
    {
        static void Main(string[] args)
        {
            C1 c1 = new C1();
            Console.WriteLine(c1.GetName());//输出“祥叔”

            C2 c2 = new C2();
            Console.WriteLine(c2.GetName());//输出“xiangshu”

            //重点看这里,和上面的重写作比较

            C1 c3 = new C2();
            Console.WriteLine(c3.GetName());//输出“祥叔” 
        }
    }
    public class C1
    {
        public string GetName()
        {
            return "祥叔";
        }
    }

    public class C2 : C1
    {
        public new string GetName()
        {
            return "xiangshu";
        }
    }


与上面的例子说明类似的问题,不过还说明了:

1.不管是重写还是覆盖都不会影响父类自身的功能,即是,父类指针指向父类实例不会受到影响

2.父类指针指向派生类实例才会受到影响,是否执行多态。。

3.同时派生类指针指向派生类实例也不会受到影响

给出一个比较综合的msdn上的例子:

class Program
    {
        static void Main(string[] args)
        {
            BaseClass bc = new BaseClass();
            DerivedClass dc = new DerivedClass();
            BaseClass bcdc = new DerivedClass();

            // The following two calls do what you would expect. They call
            // the methods that are defined in BaseClass.
            bc.Method1();
            bc.Method2();
            // Output:
            // Base - Method1
            // Base - Method2

            // The following two calls do what you would expect. They call
            // the methods that are defined in DerivedClass.
            dc.Method1();
            dc.Method2();
            // Output:
            // Derived - Method1
            // Derived - Method2

            // The following two calls produce different results, depending 
            // on whether override (Method1) or new (Method2) is used.
            bcdc.Method1();
            bcdc.Method2();
            // Output:
            // Derived - Method1
            // Base - Method2
        }
    }

    class BaseClass
    {
        public virtual void Method1()
        {
            Console.WriteLine("Base - Method1");
        }

        public virtual void Method2()
        {
            Console.WriteLine("Base - Method2");
        }
    }

    class DerivedClass : BaseClass
    {
        public override void Method1()
        {
            Console.WriteLine("Derived - Method1");
        }

        public new void Method2()
        {
            Console.WriteLine("Derived - Method2");
        }
    }


但是刚才的总结并不全面,再来看下面的例子:

class Program
    {
        static void Main(string[] args)
        {
            // Declare objects of the derived classes and test which version
            // of ShowDetails is run, base or derived.
            TestCars1();

            // Declare objects of the base class, instantiated with the
            // derived classes, and repeat the tests.
            TestCars2();

            // Declare objects of the derived classes and call ShowDetails
            // directly.
            TestCars3();

            // Declare objects of the base class, instantiated with the
            // derived classes, and repeat the tests.
            TestCars4();
        }

        public static void TestCars1()
        {
            System.Console.WriteLine("\nTestCars1");
            System.Console.WriteLine("----------");

            Car car1 = new Car();
            car1.DescribeCar();
            System.Console.WriteLine("----------");

            // Notice the output from this test case. The new modifier is
            // used in the definition of ShowDetails in the ConvertibleCar
            // class.  
            ConvertibleCar car2 = new ConvertibleCar();
            car2.DescribeCar();
            System.Console.WriteLine("----------");

            Minivan car3 = new Minivan();
            car3.DescribeCar();
            System.Console.WriteLine("----------");
        }
        // Output:
        // TestCars1
        // ----------
        // Four wheels and an engine.
        // Standard transportation.
        // ----------
        // Four wheels and an engine.
        // Standard transportation.
        // ----------
        // Four wheels and an engine.
        // Carries seven people.
        // ----------

        public static void TestCars2()
        {
            System.Console.WriteLine("\nTestCars2");
            System.Console.WriteLine("----------");

            var cars = new List<Car> { new Car(), new ConvertibleCar(), 
                new Minivan() };

            foreach (var car in cars)
            {
                car.DescribeCar();
                System.Console.WriteLine("----------");
            }
        }
        // Output:
        // TestCars2
        // ----------
        // Four wheels and an engine.
        // Standard transportation.
        // ----------
        // Four wheels and an engine.
        // Standard transportation.
        // ----------
        // Four wheels and an engine.
        // Carries seven people.
        // ----------

        public static void TestCars3()
        {
            System.Console.WriteLine("\nTestCars3");
            System.Console.WriteLine("----------");
            ConvertibleCar car2 = new ConvertibleCar();
            Minivan car3 = new Minivan();
            car2.ShowDetails();
            car3.ShowDetails();
        }
        // Output:
        // TestCars3
        // ----------
        // A roof that opens up.
        // Carries seven people.

        public static void TestCars4()
        {
            System.Console.WriteLine("\nTestCars4");
            System.Console.WriteLine("----------");
            Car car2 = new ConvertibleCar();
            Car car3 = new Minivan();
            car2.ShowDetails();
            car3.ShowDetails();
        }
        // Output:
        // TestCars4
        // ----------
        // Standard transportation.
        // Carries seven people.
    }

    // Define the base class, Car. The class defines two virtual methods,
    // DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived
    // class also defines a ShowDetails method. The example tests which version of
    // ShowDetails is used, the base class method or the derived class method.
    class Car
    {
        public virtual void DescribeCar()
        {
            System.Console.WriteLine("Four wheels and an engine.");
            ShowDetails();
        }

        public virtual void ShowDetails()
        {
            System.Console.WriteLine("Standard transportation.");
        }
    }

    // Define the derived classes.

    // Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails
    // hides the base class method.
    class ConvertibleCar : Car
    {
        public new void ShowDetails()
        {
            System.Console.WriteLine("A roof that opens up.");
        }
    }

    // Class Minivan uses the override modifier to specify that ShowDetails
    // extends the base class method.
    class Minivan : Car
    {
        public override void ShowDetails()
        {
            System.Console.WriteLine("Carries seven people.");
        }
    }


1.子类的实例在执行父类的方法时会根据new或者override和virtual,决定是否现实多态

2.基类指针指向派生类实例时也是,基类指针默认实现基类的方法,而如果有override和virtual,就会实行多态,执行

派生类的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: