这是方法调用的后期绑定,参见《THINKING IN JAVA》第7章

解决方案 »

  1.   

    Super sup = new Sub();    ---print " 5 , sub "
    Sub sup = new Sub();      ---print " 2 , sub "
    why do it?
    let me tell you ,tomorrow
      

  2.   

    你sub类里重载了printVal() 方法。而index变量对super类有优先性。将sub类改为:
    class Sub extends Super
    {  
    Sub(){
    this.index = 2;
    }

      public void printVal() 
    就行了。
      {  
    System.out.println( "Sub" );
      }
    }
      
      

  3.   

    我想 love722915(xiaojun) 提到了要点!Super sup = new Sub();  
    Sub sup = new Sub();  两者之间的区别,我没有见过前者的方式,期盼完美的回复!
      

  4.   

    java中绑定的所有方法都采用后期绑定技术。这是多形性。
      

  5.   

    下面是一段java tutorial中的关于继承的一段说明:
    Subclasses inherit those superclass members declared as public or protected. 
    Subclasses inherit those superclass members declared with no access specifier as long as the subclass is in the same package as the superclass. 
    Subclasses don't inherit a superclass's member if the subclass declares a member with the same name. In the case of member variables, the member variable in the subclass hides the one in the superclass. In the case of methods, the method in the subclass overrides the one in the superclass. 请看In the case of member vairables,...。此处子类只是隐藏了父类的成员变量。而In the case of methods, 子类覆盖了父类的方法。见下面的例程:
    class T1 {
    int i = 1;
    public int getInt() {
    return i;
    }
    }
    class T2 extends T1 {
    int i = 2;
    public int getInt() {
    return i;
    }
    public int getSuper() {
    return super.i;
    }    public static void main(String[] args) {
            T1 t1 = new T1();
            T2 t2 = new T2();
            T1 t3 = new T2();
            
            System.out.println(t1.getClass().getName());
            System.out.println(t2.getClass().getName());
            System.out.println(t3.getClass().getName());        System.out.println(t2.i);
            System.out.println(((T2)t3).i);
            
            System.out.println("t1.i=" + t1.i);
            System.out.println("t1.getInt()=" + t1.getInt());
            System.out.println("t2.i=" + t2.i);
            System.out.println("t2.super.i=" + t2.getSuper());
            System.out.println("t2.getInt()=" + t2.getInt());
            System.out.println("t3.i=" + t3.i);
            System.out.println("t3.getInt()=" + t3.getInt());
    }
    }
    结果:
    T1
    T2
    T2
    2
    2
    t1.i=1
    t1.getInt()=1
    t2.i=2
    t2.super.i=1
    t2.getInt()=2
    t3.i=1
    t3.getInt()=2说明:
    1、无论你在新建实例(对象)时,用父类还是子类的句柄,其实例的类是其本身的类。即构造器的类。所以t2和t3都是T2类的实例。t2无非是将t3进行了一次上朔造型(upcast)。即T1 t2 = new T2();完全等价于T1 t2 = (T1)t3;(见结果的第四行和第五行)。
    2、关于在继承中对于类成员变量和方法的不同对待。即如果在子类中成员变量与父类的同名,则隐藏父类的成员变量。但可以通过上朔造型来访问。而对于方法则不行。如果子类中方法与父类的同名,则该子类的实例必然调用子类的方法,因为是方法已经被覆盖。至于为什么这样,我想可能和面向对象的思想有关吧。具体我说不好,也就是说这样的设计能够让我们更好或是更正确地进行抽象和反映现实世界。想了个例子:父类:动物
    子类:人class Animal {
    int weight;
    void eat() {
    ...
    }
    }class Human extends Animal {
    int weight;
    void eat() {
    ...
    }
    public static void main(String[] args) {
    Animal h = new Human();
    ...
    a = h.weight;
    b = ((Animal)h).weight;
    h.eat();
    ...
    }
    }大家知道,类中的成员变量代表类的一种状态,比如Animal中的weight代表动物的重量。而方法代表类的一种行为,比如Animal中的eat()代表动物的吃的行为。
    而Human继承了Animal,大家看到,Human类中eat()方法被覆盖,这很好理解,人的吃的行为与自己的父类动物的吃行为有不同。所以不管你的句柄是动物还是人(即你把一个人看成是一个动物还是一个人),作为一个人类的实例,他(它)的吃行为都是人的吃行为。而对于代表状态的成员变量就有些令人迷惑。因为如果你的Human类中的weight是表示体重的话,那和动物的weight是一个意思,没有必要再次申明,用父类的weight即可。如果这里的weight是表达人的另一种状态的话,则用隐藏来实现这种关系则非常合适。如果用覆盖的话,我们无法访问从父类继承的weight,也就是说人在继承时丢失了weight这种状态或属性。这是不合理的。所以这里为了避免不必要的混淆,就不要在继承时申明父类已有的成员变量。说了不少,不知道是否表达得清楚。
    :)
      

  6.   

    hawaii(hawaii) 够意思! 谢了