class Base {
int i = 99;
public void amethod () {
System.out.println (“Base.amethod ()”);
}
}
public class RType extends Base {
int i = -1;
public static void main (String argv []) {
Base b = new RType (); //<= Note the type
System.out.println (b.i);
b.amethod ();
}
public void amethod () {
System.out.println (“RType.amethod ()”);
}
}結果:
99
RType.amethod ()
提示:
注意,b 引用的类型是Base,但是实际的类型是类RType。对amethod 的调用将启动
RType 中的版本,但是b.i 输出的调用将引用Base 类中的域i。
为什么是99呢?? 搞不懂!!!

解决方案 »

  1.   

    rtype继承了base,就包括把base的i的属性也继承下来,所以,取的值是-1
      

  2.   

    When a method accesses an object's member that has been redefined in a subclass, to which member will the method referthe superclass member or the subclass member? The answer to that depends on the kind of member, its accessibility, and how you refer to it.When you invoke a method through an object reference, the actual class of the object governs which implementation is used. When you access a field, the declared type of the reference is used. The following example will help explain:class SuperShow {
        public String str = "SuperStr";    public void show() {
             System.out.println("Super.show: " + str);
        }
    }class ExtendShow extends SuperShow {
        public String str = "ExtendStr";    public void show() {
             System.out.println("Extend.show: " + str);    }    public static void main(String[] args) {
            ExtendShow ext = new ExtendShow();
            SuperShow sup = ext;
            sup.show();
            ext.show();
            System.out.println("sup.str = " + sup.str);
            System.out.println("ext.str = " + ext.str);
        }
    }There is only one object, but we have two variables containing references to it: One variable has type SuperShow (the superclass) and the other variable has type ExtendedShow (the actual class). Here is the output of the example when run:Extend.show: ExtendStr
    Extend.show: ExtendStr
    sup.str = SuperStr
    ext.str = ExtendStrFor the show method, the behavior is as you expect: The actual class of the object, not the type of the reference, governs which version of the method is called. When you have an ExtendShow object, invoking show always calls ExtendShow's show even if you access it through a reference declared with the type SuperShow. This occurs whether show is invoked externally (as in the example) or internally within another method of either ExtendShow or SuperShow.For the str field, the type of the reference, not the actual class of the object, determines which class's field is accessed. In fact, each ExtendShow object has two String fields, both called str, one of which is hidden by ExtendShow's own, different field called str
      

  3.   

    The field that gets accessed is determined at compile time based on the type of the reference used to access it.Inside a method, such as show, a reference to a field always refers to the field declared in the class in which the method is declared, or else to an inherited field if there is no declaration in that class. So in SuperShow.show the reference to str is to SuperShow.str, whereas in ExtendShow.show the reference to str is to ExtendShow.str.You've already seen that method overriding enables you to extend existing code by reusing it with objects of expanded, specialized functionality not foreseen by the inventor of the original code. But where fields are concerned, it is hard to think of cases in which hiding them is a useful feature.If an existing method had a parameter of type SuperShow and accessed str with that object's reference, it would always get SuperShow.str even if the method were actually handed an object of type ExtendShow. If the classes were designed to use a method instead of a field to access the string, the overriding method would be invoked in such a case and the ExtendShow.str could be returned. This hiding behavior is often another reason to prefer defining classes with private data accessed only by methods, which are overridden, not hidden.Hiding fields is allowed because implementors of existing superclasses must be free to add new public or protected fields without breaking subclasses. If the language forbade using the same field name in a superclass and a subclass, adding a new field to an existing superclass could potentially break any subclasses already using those names.If adding new fields to existing superclasses would break some unknown number of subclasses, you'd be effectively immobilized, unable to add public or protected fields to a superclass. Purists might well argue that classes should have only private data, but you get to decide on your style.
      

  4.   

    你的 Base b = new RType ();
    改成RType b = new RType ();
    你就知道了
      

  5.   

    Base b = new RType ();
    b.amethod ();
    ////这种情况下,在java中就规定,调用的是派生类中的重载了基类的方法.
    但是在这里,成员变量并未被覆盖掉