zoukankan      html  css  js  c++  java
  • 天轰穿C# vs2010 04面向对象的编程之隐藏基类方法【原创】

    小天:上面你说了个用new可以隐藏基类方法,这个怎么说?

    老田:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。隐藏继承的成员时,该成员的派生版本将替换基类版本。虽然可以在不使用 new 修饰符的情况下隐藏成员,但会生成警告。如果使用 new 显式隐藏成员,则会取消此警告,并记录要替换为派生版本这一事实。

    小天:哦,明白了,也就是说用virtual修饰的成员还是存在的,只是成为了多态中的一种“态”。而使用new关键字则实实在在是将基类的方法给替换掉了,对吧?

    老田:是的,若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并使用 new 修饰符修饰该成员。例如:

        public class BaseC

        {

            public int x;

            public void Invoke()

            {

                //方法体

            }

        }

        public class DerivedC : BaseC

        {

            new public void Invoke()  //尝试将new关键字的位置换换玩吧

            {

                //方法体

            }

        }

    在此示例中,DerivedC.Invoke 隐藏了 BaseC.Invoke。字段 x 不受影响,因为它没有被类似名称的字段隐藏。

    通过继承隐藏名称采用下列形式之一:

    ·         引入类或结构中的常数、指定、属性或类型隐藏具有相同名称的所有基类成员。

    ·         引入类或结构中的方法隐藏基类中具有相同名称的属性、字段和类型。同时也隐藏具有相同签名的所有基类方法。

    ·         引入类或结构中的索引器将隐藏具有相同名称的所有基类索引器。

    对同一成员同时使用 new override 是错误的做法,因为这两个修饰符的含义互斥。new 修饰符会用同样的名称创建一个新成员并使原始成员变为隐藏的。override 修饰符会扩展继承成员的实现。

    VS中编写代码的时候,如果不隐藏继承成员的声明中使用 new 修饰符将会生成警告。

    小天:这个和虚方法有什么不同?

    老田:这个就不解释了,下面这个实例:注意一定要用断点调试模式,一行行的看下编译器是怎么找到具体执行方法的,看完或许你就懂了。

        //基类 A

        public class A

        {

            public virtual void prinf()

            {

                Console.WriteLine("这是虚方法");

            }

        }

        //基类  B

        public class B : A   

        {

            public override void prinf()  //使用override重写基类方法

            {

                Console.WriteLine("这是新的方法");

            }

        }

        //基类  C

        public class C : A

        {

            public new void prinf()  //使用new 修饰符隐藏基类方法

            {

                Console.WriteLine("这是另一个新的方法");

            }

        }

     

        //本例是一个控制台应用程序,用于演示如何使用上面的类

        class Program

        {

            static void Main(string[] args)

            {

                A a1 = new B();

                A a2 = new C();

                B b1 = (B)a1;

                C c1 = (C)a2;

                a1.prinf(); //结果显示为  这是新的方法

                a2.prinf(); //结果显示为  这是虚方法

                b1.prinf(); //结果显示为  这是新的方法

                c1.prinf(); //结果显示为  这是另一个新的方法

     

                Console.ReadLine();

            }

        }

    小天:哦,明白了,原来当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类(等号前面的类),即申明类,看所调用的函数是否为虚函数。如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类(等号后面的类)。

    但是对于new函数则是直接在申明类中找到方法就执行。

    本文章为天轰穿原创作品,转载请注明出处及作者。

  • 相关阅读:
    Python mutilprocessing Processing 父子进程共享文件对象?
    BZOJ4836: [Lydsy1704月赛]二元运算
    博弈论刷题记录
    manacher(无讲解)
    UOJ_407_【IOI2018】狼人
    BZOJ_3935_Rbtree
    dsu on tree(无讲解)
    BZOJ_3744_Gty的妹子序列
    后缀数组(无讲解)
    虚树(无讲解)
  • 原文地址:https://www.cnblogs.com/thcjp/p/2864293.html
Copyright © 2011-2022 走看看