分析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//普通方法被覆盖,实现了多态

原文地址:https://www.cnblogs.com/beta2013/p/3377418.html