scjp 最经典的问题,还是不明白,大家看看!!

wren4255 2008-03-28 03:18:10
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呢?? 搞不懂!!!
...全文
161 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Z8157522 2008-03-29
  • 打赏
  • 举报
回复
以前看过类似的帖。。记得好象说过。变量是静态邦定的。。。子类的类型调用i,我的理解应该是-1。但是。。怎么会是99
mdog26 2008-03-29
  • 打赏
  • 举报
回复
2,8楼是对的啊,这里只有方法覆盖了,变量是继承下来的,父类的引用当然调用的父类的变量啊!
雨过白鹭洲 2008-03-28
  • 打赏
  • 举报
回复
MM解释得很有道理
rabbit_zizhu 2008-03-28
  • 打赏
  • 举报
回复
Base b = new RType ();
b.amethod ();
////这种情况下,在java中就规定,调用的是派生类中的重载了基类的方法.
但是在这里,成员变量并未被覆盖掉
linmen1983 2008-03-28
  • 打赏
  • 举报
回复
你的 Base b = new RType ();
改成RType b = new RType ();
你就知道了
胡矣 2008-03-28
  • 打赏
  • 举报
回复
这个就是多态,似乎有点不负责任的回答.呵呵
CpRcF 2008-03-28
  • 打赏
  • 举报
回复
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.

CpRcF 2008-03-28
  • 打赏
  • 举报
回复
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 = ExtendStr



For 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

奔跑吧男人 2008-03-28
  • 打赏
  • 举报
回复
留记号看人解决
hoszone 2008-03-28
  • 打赏
  • 举报
回复
方法有重写,变量没有重写.
hopegood 2008-03-28
  • 打赏
  • 举报
回复
rtype继承了base,就包括把base的i的属性也继承下来,所以,取的值是-1

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧