问题描述
最近我们公司招人,看了下笔试题,有道题不理解题目如下classSuperClass{privateintnumber;publicSuperClass(){this.number=0;}publicSuperClass(intnumber){this.number=number;}publicintgetNumber(){number++;returnnumber;}}classSubClass1extendsSuperClass{publicSubClass1(intnumber){super(number);}}classSubClass2extendsSuperClass{privateintnumber;publicSubClass2(intnumber){super(number);}}publicclassSubClassextendsSuperClass{privateintnumber;publicSubClass(intnumber){super(number);}publicintgetNumber(){number++;returnnumber;}publicstaticvoidmain(String[]args){SuperClasss=newSubClass(20);SuperClasss1=newSubClass1(20);SuperClasss2=newSubClass2(20);System.out.println(s.getNumber());System.out.println(s1.getNumber());System.out.println(s2.getNumber());}}执行结果是12121请问:s.getNumber()结果为什么是1啊?!!
解决方案
解决方案二:
该回复于2011-03-18 09:14:34被版主删除
解决方案三:
因为subclass构造函数中的number是赋值给superclass的subclass本身变量number值并没有改变还是初始值0;
解决方案四:
继承过程中只能继承公共变量private所修饰的变量是不能继承的所以subclass中的number还是自己的而不是父类的s.getNumber()调用自身的方法-->自身的number++自身的number初值是0所以最后结果是1
解决方案五:
SubClass2也是privateintnumber;为什么得出的结果是21????引用3楼tkd03072010的回复:
继承过程中只能继承公共变量private所修饰的变量是不能继承的所以subclass中的number还是自己的而不是父类的s.getNumber()调用自身的方法-->自身的number++自身的number初值是0所以最后结果是1
解决方案六:
引用3楼tkd03072010的回复:
继承过程中只能继承公共变量private所修饰的变量是不能继承的所以subclass中的number还是自己的而不是父类的s.getNumber()调用自身的方法-->自身的number++自身的number初值是0所以最后结果是1
顶顶!!
解决方案七:
引用4楼h602miss的回复:
SubClass2也是privateintnumber;为什么得出的结果是21????引用3楼tkd03072010的回复:继承过程中只能继承公共变量private所修饰的变量是不能继承的所以subclass中的number还是自己的而不是父类的s.getNumber()调用自身的方法-->自身的number++自身的number初值是0所以最后结果……
3楼的说的对!SubClass2也是privateintnumber;但是它在构造方法里调用了super(number);所以和它自己的number没关系的。可以在SubClass2的构造方法用this.number来打印看看,这个值是0。
解决方案八:
publicclassSubClassextendsSuperClass{privateintnumber;publicSubClass(intnumber){super(number);}publicintgetNumber(){number++;returnnumber;}
此代码中当newSubClass(20)的时候,调用构造函数publicSubClass(intnumber)方法,super(number)中的number变量是指的publicSubClass(intnumber)中的number,它是一个局部变量,作用域只限于构造函数。而SubClass类的成员变量privateintnumber初始化为0,所以执行number++以后就变为了1.这应该是考变量作用域以及继承方面的知识。
解决方案九:
从来没见过这么复杂的继承,而且是父类引用指和子类对象,需要绕很多弯呢。
解决方案十:
回去得好好推敲一翻。
解决方案十一:
我看了半天,同意7楼的,super(number)这句话改变的是superClass中的number值。在SubClass1,SubClass2没有重写getNumber()方法,所以输出的是superClass中的number,因为在SubClass中重写了getNumber()方法,所以在SnbClass中输出本身的number,因为初始值为0,所以输出为1
解决方案十二:
局部变量可以和实例变量冲突,但是冲突时局部变量优先
解决方案十三:
该回复于2011-03-19 09:10:47被版主删除
解决方案十四:
SubClass的构造函数只对父类的number赋值,SubClass的number属性未赋值是默认的,调用getNumber时调用的是子类覆写的方法,子类覆写的方法调用的number是子类的值,固为1
解决方案十五:
主要是subclass重写了父类的getnum方法
解决方案:
回去得好好推敲一翻。
解决方案:
intnumber是私有变量,子类不能继承,所以调用super(20)时,被赋值的是父类里面的number,子类里面的number并没有被赋值。在SubClass类中覆盖了父类的getNumber(),返回的是当前子类的number,但在对象声明时并没有被赋值,因此返回的是number初始值+1;而SubClass1和SubClass2继承了父类的getNumber(),返回的也是父类的number,在对象声明时已经被赋值。综上所述,得出的结论就是s.getNumber()==1;s1.getNumber()==21;s2.getNumber()==21。
解决方案:
该回复于2011-03-19 10:15:58被版主删除
解决方案:
该回复于2011-03-19 10:17:55被版主删除
解决方案:
这什么垃圾代码来的,靠,乱七八糟的
解决方案:
该回复于2011-03-19 08:42:42被版主删除
解决方案:
引用19楼liangzhongqin的回复:
这什么垃圾代码来的,靠,乱七八糟的
不急,慢慢来,打开netbeans,把代码放进去,然后格式化代码,并且根据提示加上@Override,然后看到一般情况下大家喜欢的格式:/**Tochangethistemplate,chooseTools|Templates*andopenthetemplateintheeditor.*/packagemytester;/****@authorRains.C*/publicclassMain{/***@paramargsthecommandlinearguments*/publicstaticvoidmain(String[]args){//TODOcodeapplicationlogichereSuperClasss=newSubClass(20);SuperClasss1=newSubClass1(20);SuperClasss2=newSubClass2(20);System.out.println(s.getNumber());System.out.println(s1.getNumber());System.out.println(s2.getNumber());}}classSuperClass{privateintnumber;publicSuperClass(){this.number=0;}publicSuperClass(intnumber){this.number=number;}publicintgetNumber(){number++;returnnumber;}}classSubClass1extendsSuperClass{publicSubClass1(intnumber){super(number);}}classSubClass2extendsSuperClass{privateintnumber;publicSubClass2(intnumber){super(number);}}classSubClassextendsSuperClass{privateintnumber;publicSubClass(intnumber){super(number);}@OverridepublicintgetNumber(){number++;returnnumber;}}
在第21,22,23,24行打上断点符号,然后“调试”主项目:运行第21行之前,结果是(netbeans显示):s有自己的number=0,继承的number=20s1只有继承的number=20s2有自己的number=0,继承的number=20然后“继续”(运行第22行之前)结果是:s自己的number=1,继承的number=20其他不变然后继续:(运行第23行之前)s不变s1继承的number=21其他不变然后继续(运行第24行之前):s和s1不变s2自己的number=0,继承的number=21调试结束。整个过秤的变量中间结果如此,现在反过来推敲是什么步骤导致这样的中间结果。首先变化的是s自己的number,继承的number不变。这个动作由21行的s.getNumber()引起,观察s的定义:s是鸡肋(基类),用子类填充(实例化),子类实例化的具体步骤是super(number),即调用鸡肋的构造器。鸡肋的构造器对鸡肋自己的number赋值,这个很好理解。如果我没有看错的话(现在是凌晨2点30,我希望我没看走眼),3个子类的构造器通通是调用鸡肋的,观察“调试”模式的变量中间结果,可以很轻易的得到结论:number域可以被继承。因此,第21行执行前,S,S1,S2三个对象的继承来的number域都是20,这个由18,19,20行的实例化方式及参数看得出。回到s.getNumber()方法,这个方法返回的是子类-自己-的number域,系统为这个未初始化的域赋予默认值0,那么get以后得到1,很好理解。继续,s1.getNumber()方法:s1没有定义这个方法,系统找s1的鸡肋的public的getNumber方法,找到了!之行……结果是s1的继承来的number域变成21,嗯,正如所料。继续,s2.getNumber()方法:和s1没区别;另一个证据是:在netbeans里面,SubClass2的number域下面有波浪线,系统提示:“未使用字段”。我模仿处女座举证的方式,罗列了netbeans中的事实,供大家思考。有一些建议如下:1、建议非对象的私有域最好给个初值,比如int=0;如果私有域是对象,最好给个Null,反而不要赋值,避免递归定义,堆栈溢出,比如:publicclassA{privateAa=null;//privateAa=newA();}
很难说你的构造器里面有if(A!=null)return;2、域放在方法后面,除非写算法。3、继承和接口,首先考虑接口。4、尽量不用默认的访问控制,把域标记为private而不是空着,然后提供访问器和设置器。——from《EffectiveJava》
解决方案:
SuperClasss1=newSubClass1(20);创建s1对象时,调用的是父类的带参数的构造方法,于是父类number=20;因为子类SubClass1没有重写父类的getNumber()的方法,只能从父类继承,所以getNumber()所取得的值是父类的number+1;
解决方案:
该回复于2011-03-19 11:00:58被版主删除
解决方案:
引用19楼liangzhongqin的回复:
这什么垃圾代码来的,靠,乱七八糟的
真的很有耐心啊,我没耐心看完,但是貌似你的思路是对的。
解决方案:
引用22楼dengsir200803010213的回复:
SuperClasss1=newSubClass1(20);创建s1对象时,调用的是父类的带参数的构造方法,于是父类number=20;因为子类SubClass1没有重写父类的getNumber()的方法,只能从父类继承,所以getNumber()所取得的值是父类的number+1;
我是想说说22楼的啊
解决方案:
看来我是不会的
解决方案:
这明显是笔试题。
解决方案:
20楼讲的好cei类啊
解决方案:
不错,会做这题,对继承的理解加深了很多啊
解决方案:
主要还是subclass重写了getNumber方法又因为subclass的变量时私有的导致subclass的值为1而subclass2没有重写getNumber方法subclass2又继承了superclass导致getNumber方法返回的是21
解决方案:
真是绕啊。
解决方案:
不难呀。理解好了继承就OK了。楼上很多施主已经说了。
解决方案:
很简单的识别方法:SuperClasss=newSubClass(20);//根据newSubClass(20);20是进入SubClass的构造方法。SuperClasss1=newSubClass1(20);SuperClasss2=newSubClass2(20);System.out.println(s.getNumber());//根据第一行SuperClasss;getNumber()是进入SuperClass的方法。System.out.println(s1.getNumber());System.out.println(s2.getNumber());
解决方案:
错了//根据第一行SuperClasss=newSubClass(20);;getNumber()是进入SubClass的方法。
解决方案:
回去得好好推敲一翻
解决方案:
SuperClasss=newSubClass(20);子类重写了getNumber()方法!实现了多态!并且父类的number是private是不能继承的!只能用自己的!而自己的初始值是0所以getNumber()后是1;下面两个很容易理解!
解决方案:
这样的题当初要毕业的时候求职做了很多,现在看到就想吐槽……
解决方案:
考的是getNumber()方法在subClass里面的override
解决方案:
开始时继承父类的方法,本身的初值this.number=0,但是在方法的执行时number++,所以结果就是1
解决方案:
主要考的是继承
解决方案:
继承过程中只能继承公共变量private所修饰的变量是不能继承的所以subclass中的number还是自己的而不是父类的s.getNumber()调用自身的方法-->自身的number++自身的number初值是0所以最后结果是1
解决方案:
这是多态性,覆盖,子类覆盖了父类的getNumber(),调用是会检查,如果子类有自己的getNumber()方法则执行子类的,没有就执行父类的
解决方案:
多态了,subclass对象的引用给了superclass,调用的是subclass的getNumebr,subclass的getnumber操作的是自己的number变量,构造器赋予的number变量给父类了。
解决方案:
错错错私有的变量可以继承不然子类的调用父类的get私有变量的方法怎么可以。。。可以继承不能直接访问。。
解决方案:
引用4楼h602miss的回复:
SubClass2也是privateintnumber;为什么得出的结果是21????引用3楼tkd03072010的回复:继承过程中只能继承公共变量private所修饰的变量是不能继承的所以subclass中的number还是自己的而不是父类的s.getNumber()调用自身的方法-->自身的number++自身的number初值是0所以最后结果是1……
s2.getNumber()是调用superClass的方法。
解决方案:
引用44楼hyl7733的回复:
错错错私有的变量可以继承不然子类的调用父类的get私有变量的方法怎么可以。。。可以继承不能直接访问。。
你可以这样理解,但不可有这种说法吧!私有的是不能被继承的!
解决方案:
引用21楼rainsego的回复:
引用19楼liangzhongqin的回复:这什么垃圾代码来的,靠,乱七八糟的不急,慢慢来,打开netbeans,把代码放进去,然后格式化代码,并且根据提示加上@Override,然后看到一般情况下大家喜欢的格式:Javacode/**Tochangethistemplate,chooseTools|Templates*a……
顶顶....
解决方案:
这个没有什么绕的,你们没有理解透java机制,我换种写法你们就不难理解了。classSubClass1extendsSuperClass{publicSubClass1(intnumber){super.number=number;}//getNumber方法没有被继承,多态时使用父类方法}classSubClass2extendsSuperClass{privateintnumber;publicSubClass2(intnumber){super.number=number;}//getNumber方法没有被继承,多态时使用父类方法}publicclassSubClassextendsSuperClass{privateintnumber;publicSubClass(intnumber){super.number=number;}publicintgetNumber(){this.number++;returnthis.number;}
解决方案:
java参数传递分为值传递和址传递,这种属于值传递,只是复制数据而已
解决方案:
楼上理解错了,考察的不是值传递还是地址传递它考察的是在多态的情况下,子类与父类同名成员,同名方法的问题。