zoukankan      html  css  js  c++  java
  • 分析JAVA、C#、C++的“覆盖”和“隐藏”与多态的实现

    隐藏字段   :字段不可以被覆盖而只能被隐藏。
    可访问性与覆盖   :一个方法只有当它可以被访问时才可以被覆盖。
    隐藏静态成员   :类中的静态成员(无论是字段还是方法)不可以被覆盖,只能被隐藏。

    由以上可推出,JAVA中基类与子类若有同签名的函数,则基类中的此函数一定要被子类覆盖掉,相应地基类中的此函数也一定不能为private,理由根据上述第二点。而C#中却不必如此,在这点上C#做得要显明得多,即基类方法加virtual关键字,而子类方法再override表示覆盖,加new关键字表示隐藏。在这一点上,C#与C++相似,在C++中,若基类方法加了virtual关键字,则子类方法的继承规则是“覆盖”,若基类方法无virtual关键字,则为“隐藏”。即C#与C++的默认方式都是隐藏,即都会把基类的方法拷贝一份过来,除非使用关键字显示告诉编译器我要覆盖。这一点在功能上来说,JAVA显得不到位,因为它无法做到“隐藏”这一功能,即同签名的基类方法子类无法再拥有。所以:多态只不过就是实现了“覆盖”,当实现了“覆盖”,虽然是基类类型,但因为子类的方法将基类的方法覆盖掉了,所以以“基类类型.方法名()”的方式去调用时,内存中只存在被子类所覆盖重写的方法,即实现了多态“根据运行期实际的对象调用其方法,而不是只根据其类型”。

    理解以上原则后再去探究一下以下代码:
    import java.io.*;
    class A{   
    static String s1 ="staticA";  
    String s2 = "A";      
    static void getString1() {
          System.out.println(s1); 
            }
         void getString2() {
          System.out.println(s2); 
            }     
    }
    class B extends A {
    static String s1="staticB";
        String s2 = "B";
        static void getString1() {
          System.out.println(s1); 
            }
         void getString2() {
          System.out.println(s2); 
            }   
    }
    public class test01 {
    public static void main(String[] args) {
      A a = new B();
      System.out.println("a.s1="+a.s1);
      System.out.println("a.s2="+a.s2);
      a.getString1();
      a.getString2();
    }
    }

    //    运行结果:
    //            a.s1=staticA//字段不可以被覆盖而只能被隐藏。即字段无法实现多态
    //            a.s2=A//同上
    //            staticA//静态成员(不管是字段还是方法)不可以被覆盖而只能被隐藏。即静态成员无法实现多态
    //            B//普通方法被覆盖,实现了多态

  • 相关阅读:
    诚聘Python等课程兼职讲师
    Ogre3d
    OGRE中 场景管理器,场景节点和实体
    第四天:原型模式建造者模式
    第二天:装饰模式及面向对象设计原则4则
    表达式求值:面向对象版本
    第五天:模板方法外观模式观察者模式
    第三天:代理模式工厂方法抽象工厂
    第一天:简单工厂与策略模式
    idea files count
  • 原文地址:https://www.cnblogs.com/beta2013/p/3377418.html
Copyright © 2011-2022 走看看