class S1{
String s="S1";
void a(){
System.out.println(s);
}
}
class S2 extends S1{
String s="S2";
}
public class Example {
String s="Outer";
public static void main(String[] args) {
S2 s2=new S2();
s2.a();
}
}
这段代码为什么结果是S1啊?
String s="S1";
void a(){
System.out.println(s);
}
}
class S2 extends S1{
String s="S2";
}
public class Example {
String s="Outer";
public static void main(String[] args) {
S2 s2=new S2();
s2.a();
}
}
这段代码为什么结果是S1啊?
class S2 extends S1{
String s="S2";
void a(){
System.out.println(s);
}
}那么结果就是“S2”了,可能是因为s2中有a()这个方法,所以运行a()的时候结果是“s2”
当s2没有a()方法是,就向父类找这个方法,当找到之后就直接运行父类的a(),当然这个
a()也理所当然的用自己,也就是父类中的s了`
laolaocao(加勒比强盗)给的方法是正确的
但是解释似乎不太准确复写的应该是方法(method)
而不会是变量
你在class S2中“复写”变量s是不成功的
实际上你得到了另一个变量而laolaocao(加勒比强盗)的 class S2 复写了 method a()
如果写成这样
class S2 extends S1{
String s="S2";
void a(){
System.out.println(super.s);
}
}
结果会还是"S1"
原因我想你现在应该明白了
http://www.cjsdn.net/post/view?bid=1&id=26573&tpg=1&ppg=1&sty=1&age=0#26573可能是JAVA的规则.同名覆盖上,在子类对象中函数上父类对子类隐藏,
变量上子类对父类隐藏.不知道这样的理解是否正确。还望老手指教~
各自的Constructor设置各自的s输出时,没有override,就不是动态联编,
s2被声明为什么类型,那就输出那个类型的s一楼的老兄说的是对的。望高手能讲根本质的原理~
子类S2中未定义a()方法,因此在子类S2实例s2上调用的a()方法是继承自复类S1中的,
由于a()方法只能对同类上的类成员变量s进行访问,因此输出S1
这里面涉及到两个JAVA的核心问题,第一个是继承的问题,先来看<Thinking in java>里面的一段话:
But inheritance doesn’t just copy the interface of the base class. When you create an object of the derived class, it contains within it a subobject of the base class. This subobject is the same as if you had created an object of the base class by itself. It’s just that, from the outside, the subobject of the base class is wrapped within the derived-class object.
翻译成中文大致是说导出类(子类)不仅仅是继承基类(父类)的接口,而且在创建导出类对象的时候,它会包含一个基类的子对象, 这个子对象和从基类直接创建出来的子对象没有任何不同.只是从外面看起来, 这个子对象被导出类对象包裹在里面了.
第二个问题是继承是否会覆盖同名成员的问题, 答案是JAVA中不会覆盖任何的同名成员.
说到这里,答案基本上就出来了, S2中没有a()方法,用的是内置基类S1的a()方法, 而a()方法访问的是S1的成员s, 结果为"S1".
但有一点也需要更正, 就是JAVA中除了不会复写成员变量, 也不会复写成员方法, 这一点和C++是不同的.
void a(){
System.out.println(s);
}这里的s取的只能是S1里的s,因为你并没有把S2的对象传进来
public String a = "abc";
}class B extends A {
public String a = "def";
public void a() {
System.out.println(this.a);
System.out.println(super.a);
}
}S2的对象没有a方法,所以,调用父类(S1)的a方法,S1类使用S1.s变量。