zoukankan      html  css  js  c++  java
  • 关于C#多态的思考

    C# 中,可以如下定义:

    Base father = new Derived();

    father 是基类引用,指向子类对象,这一点有点类似C++。

    该引用的使用模式如下(先说结论)——

    • father引用 可以调用所有 非virtual方法(废话);
    • father 会自动调用子类 override方法(多态);
    • father 无法调用子类新增的方法;
    • 对于子类与父类同名但非override的方法,需要添加new关键字。这时调用是根据 father 的类型确定;

    测试代码如下:

    using logging;
    
    class Base{
        public virtual void show(){
            Log.print("method of Base::show()");
        }
    
        public virtual void show2(){
            Log.print("method of Base::show2()");
        }
    
        public void myself(){  // without virtual.
            Log.print("method of Base::myself()");
        }
    }
    
    class Derived: Base{
        public override void show(){
            Log.print("method of Derived::show()");
        }
    
        public void show2(){  // without override, so should use 'new'
            Log.print("method of Derived::show2()");
        }
    
        public void show3(){  // a new method
            Log.print("A new method of Derived.");
        }
    
        public void myself(){  // should use 'new'
            Log.print("method of Derived::myself()");
        }
    
    
        static void Main(){
    #if BASE
            Base t = new Derived();
    #else
            var t = new Derived();  // same to 'Derived t = ...'
    #endif
            t.show();
            t.show2();
            t.show3();  // fail to compile for BASE
            t.myself();
        }
    }
    View Code

    编译 Derived father:

    $ csc tryit.cs
    Microsoft(R) Visual C# 编译器 版本 2.9.0.63208 (958f2354)
    版权所有(C) Microsoft Corporation。保留所有权利。
    
    tryit.cs(22,17): warning CS0114: '“Derived.show2()”隐藏继承的成员“Base.show2()”。若要使当前成员重写该实现,请添加关键字 override。否则,添加关键字 new。
    tryit.cs(30,17): warning CS0108: '“Derived.myself()”隐藏继承的成员“Base.myself()”。如果是有意隐藏,请使用关键字 new。
    
    method of Derived::show()
    method of Derived::show2()
    A new method of Derived::show3()
    method of Derived::myself()
    

    编译 Base father (已注释 t.show3() 调用,否则编译失败):

    $ csc tryit.cs -define:BASE
    Microsoft(R) Visual C# 编译器 版本 2.9.0.63208 (958f2354)
    版权所有(C) Microsoft Corporation。保留所有权利。
    
    tryit.cs(22,17): warning CS0114: '“Derived.show2()”隐藏继承的成员“Base.show2()”。若要使当前成员重写该实现,请添加关键字 override。否则,添加关键字 new。
    tryit.cs(30,17): warning CS0108: '“Derived.myself()”隐藏继承的成员“Base.myself()”。如果是有意隐藏,请使用关键字 new。
     
    method of Derived::show()
    method of Base::show2()
    method of Base::myself()
    

    对于 Base father = new Derived() 的形式来说,似乎是一种新老结合的方式:对于virtual方法,可以自动追寻子类的实现,而非virtual则根据Base类型决定。

    实际上,这个模式与C++完全相同,测试代码如下:

    // g++ ctry.cpp -std=c++11
    #include <stdio.h>
    
    class Base{
    public:
        // Base() = default;
        virtual void show(){
            printf("method of Base::show()
    ");
        }
    
        virtual void show2(){
            printf("method of Base::show2()
    ");
        }
    
        void myself(){  // without virtual.
            printf("method of Base::myself()
    ");
        }
    };
    
    class Derived: public Base{
    public:
        virtual void show(){
            printf("method of Derived::show()
    ");
        }
    
        void show2(){  // it would be run as virtual, though not written the keyword.
            printf("method of Derived::show2()
    ");
        }
    
        void show3(){
            printf("A new method of Derived::show3()
    ");
        }
    
        void myself(){
            printf("method of Derived::myself()
    ");
        }
    };
    
    int main(){
        Base *father = new Derived();
        father->show();
        father->show2();
        // father->show3();  // fail to compile.
        father->myself();  // call the Base::myself()
        delete father;
    }
    View Code

    编译,执行:

    $ g++ ctry.cpp -std=c++11
    
    $ ./a.exe
    method of Derived::show()
    method of Derived::show2()
    method of Base::myself()
    

    # 请忽视 C# 对show2() 的调用,那里本应该写一个override的~

  • 相关阅读:
    上传几张智能开关产品图片
    python+ueditor+七牛云存储整合
    Shell脚本检查memcache进程并自己主动重新启动
    Cocos2dx 3.x创建Layer的步骤
    HDU 5009 Paint Pearls (动态规划)
    (转)Spring4.2.5+Hibernate4.3.11+Struts2.3.24整合开发
    (转)Spring提供的CharacterEncoding和OpenSessionInView功能
    (转)为Spring集成的Hibernate配置二级缓存
    (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案二
    (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • 原文地址:https://www.cnblogs.com/brt3/p/9744070.html
Copyright © 2011-2022 走看看