我思故我强

第六部分:覆盖,重载,运行时期类型及其面向对象

第六部分:覆盖,重载,运行时期类型及其面向对象

  • 知道面向对象设计中封装的好处以及如何实现,能知道is a和has a的意义。
  • 能正确使用覆盖和重载的方法,能正确调用父类或重载的构造方法(constructor),知道调用这些方法后的结果。
  • 能正确实例化类或内部类

§1.1.1      

3. What will happen when you attempt to compile and run the following code?

class MyParent

{

int x, y;

MyParent(int x, int y)

{

this.x = x;

this.y = y;

}

public int addMe(int x, int y)

{

return this.x + x + y + this.y;

}

public int addMe(MyParent myPar)

{

return addMe(myPar.x, myPar.y);

}

}

class MyChild extends MyParent

{

int z;

MyChild (int x, int y, int z)

{

super(x,y);

this.z = z;

}

public int addMe(int x, int y, int z)

{

return this.x + x + this.y + y + this.z + z;

}

public int addMe(MyChild myChi)

{

return addMe(myChi.x, myChi.y, myChi.z);

}

public int addMe(int x, int y)

{

return this.x + x + this.y + y;

}

}

public class MySomeOne

{

public static void main(String args[])

{

MyChild myChi = new MyChild(10, 20, 30);

MyParent myPar = new MyParent(10, 20);

int x = myChi.addMe(10, 20, 30);

int y = myChi.addMe(myChi);

int z = myPar.addMe(myPar);

System.out.println(x + y + z);

}

}

 

Choices:

a. 300

b. 240

c. 120

d. 180

e. Compilation error

f. None of the above

――――――――――――

A is the correct choice. In the code, MyChild class overrides the addMe(int x, int y) method of the MyParent class. And in both the MyChild and MyParent class, addMe() method is overloaded. There is no compilation error anywhere in the above code. On execution, first, the object of MyChild class will be constructed. Please note that there is a super() call from the constructor of MyChild class, which will call the constructor of MyParent class. This will cause the value of z variable of MyChild class to be 30 and x, y variables of MyParent class will become 10 and 20 respectively. The next statement will again call the constructor of MyParent class with same x and y values. This is followed by execution of addMe() method of MyChild class with x as 10, y as 20 and z as 30. Also x and y are inherited by MyChild class from the MyParent class. Thus in the addMe() method of the MyChild class, the value of this.x will be 10, this.y will be 20 and this.z will be 30. The return value of this method will be "10 + 10 + 20 + 20 + 30 + 30", which is equal to 120. Thus x will become 120. This is followed by the invocation of the other addMe() method which takes object reference of the MyChild class. From this method, the method which was called earlier is invoked. This call is exactly the same as the earlier one. Thus the value of y will also be 120 like x. Now the addMe() method of MyParent class is invoked. This method invokes another addMe() method of the same class. Its equivalent to the invocation of addMe(int x, int y) method with x as 10 and y as 20. Also the value of instance variables x and y of My Parent class is 10 and 20 respectively. The value of z will be evaluated to "10 + 10 + 20 + 20", which is equal to 60. Thus the value of x, y and z after all the invocations will be 120, 120 and 60 respectively. As a result of this finally, "120 + 120 + 60" which is equal to 300 will be printed. Thus A is the correct choice.

 

§1.1.2      

Given the code below, and making no other changes, which access modifiers

(public, protected or private) can legally be placed before myMethod() on line 3?

If line 3 is left as it is, which keywords can legally be placed before myMethod

on line 8?

1.class HumptyDumpty

2.{

3.void myMethod() {}

4.}

5.

6.class HankyPanky extends HumptyDumpty

7.{

8.void myMethod() {}

9.}

Choices:

a. private or nothing(i.e. leaving it as it is) on line 3.

Nothing(i.e. leaving it as it is) or protected or public

on line 8.

b. public or protected on line 3. private or nothing(i.e. leaving it

as it is) on line 8.

c. nothing(i.e. leaving it as it is) or protected or public on

line 3. private or nothing(i.e. leaving it as it is) on line 8.

d. None of the above.

A is correct. The basic principle is that a method cannot be overridden to be more private. Since the method is being overridden to be friendly(default modifier) it can only be private or friendly in the superclass. Secondly if the method in superclass is left as it is(i.e. friendly access) the method in subclass can be friendly, protected or public.

§1.1.3      

What results from the following code?

1.class MyClass

2.{

3.void myMethod(int i) {System.out.println("int version");}

4.void myMethod(String s) {System.out.println("String version");}

5.public static void main(String args[])

6.{

7.MyClass obj = new MyClass();

8.char ch = 'c';

9.obj.myMethod(ch);

10.}

11.}

Choices:

a. Line 4 will not compile as void methods can't be overridden.

b. An exception at line 9.

c. Line 9 will not compile as there is no version of myMethod which takes a char as argument.

d. The code compiles and produces output: int version.

e. The code compiles and produces output: String version.

――――――――――

D is correct. A is incorrect as void methods can be overridden without any problem. B is incorrect as char ch declaration is valid. C is incorrect as char type in java is internally stored as integer and there is a method which takes int as an input. D is correct, on line 9 char ch is widened to an int and passed to int version of the myMethod(). E is incorrect as int version of myMethod() is called.

§1.1.4      

What is displayed when the following is executed?

class Parent

{

private void method1()

{

System.out.println("Parent's method1()");

}

public void method2()

{

System.out.println("Parent's method2()");

method1();

}

}

class Child extends Parent

{

public void method1()

{

System.out.println("Child's method1()");

}

public static void main(String args[])

{

Parent p = new Child();

p.method2();

}

}

Choices:

a. Compile time error

b. Run time error

c. prints : Parent's method2()

          Parent's method1()

d. prints : Parent's method2()

          Child's method1()

―――――――

C is correct. The code will compile without any error and also will not give any run time error. The variable p refers to the Child class object. The statement p.method2() on execution will first look for method2() in Child class. Since there is no method2() in child class, the method2() of Parent class will be invoked and thus "Parent's method2()" will be printed. Now from the method2() , there is a call to method1(). Please note that method1() of Parent class is private, because of which the same method (method1() of Parent class) will be invoked. Had this method(method1() of Parent class) been public/protected/friendly (default), Child's class method1() would be called. Thus C is correct answer.

 

§1.1.5      

What is displayed when the following is executed?

class Parent{

private void method1(){

System.out.println("Parent's method1()");

}

public void method2(){

System.out.println("Parent's method2()");

method1();

}

}

class Child extends Parent{

public void method1(){

System.out.println("Child's method1()");

}

public static void main(String args[]){

Parent p = new Child();

p.method2();

}

}

 

A. compile time error

B. run time error

C. prints: parent’s method2()  parent’s method1()

D. prints: parent’s method2()  child’s method1()

 

C is correct. The code will compile without any error and also will not give any run time error. The variable p refers to the Child class object. The statement p.method2() on execution will first look for method2() in Child class. Since there is no method2() in child class, the method2() of Parent class will be invoked and thus "Parent's method2()" will be printed. Now from the method2() , there is a call to method1(). Please note that method1() of Parent class is private, because of which the same method (method1() of Parent class) will be invoked. Had this method(method1() of Parent class) been public/protected/friendly (default), Child's class method1() would be called. Thus C is correct answer.

 

§1.1.6      

  1) class Person {

 

  2) public void printValue(int i, int j) { }

 

  3) public void printValue(int i){ }

 

  4) }

 

  5) public class Teacher extends Person {

 

  6) public void printValue() { }

 

  7) public void printValue(int i) {}

 

  8) public static void main(String args[]){

 

  9) Person t = new Teacher();

 

  10) t.printValue(10);

 

  11) }

 

  12) }

 

  Which method will the statement on line 10 call?

  A. on line 2

 

  B. on line 3

 

  C. on line 6

 

  D. on line 7

  翻译

  第十行的声明将调用哪些方法。

 

  答案 D

 

  解析 变量t是一个Person对象,但是它是用Teacher实例化的,这个问题涉及到java的

编译时多态和运行时多态的问题,就编译时多态来说,t实际上是一个Person类,这涉及到类

型的自动转换(将一个子类的实例赋值给一个父类的变量是不用进行强制类型转换,反之则需

要进行强制类型转换,而且被赋值的变量实际上应该是一个子类的对象),如果对t调用了子

类中新增的方法则造成编译时错误编译将不能通过,而在运行时,运行时系统将根据t实际指

向的类型调用对应的方法,对于本例来说,t.print(10)将调用t实际指向的Teacher类的对应

方法。在java中,可以用一个子类的实例实例化父类的一个变量,而变量在编译时是一个父类

实例,在运行时可能是一个子类实例。

 

§1.1.7      

35、public class Parent {

  public int addValue( int a, int b) {

  int s;

  s = a+b;

  return s;

  }

  }

  class Child extends Parent {

 

  }

  Which methods can be added into class Child?

  A. int addValue( int a, int b ){// do something...}

 

  B. public void addValue (){// do something...}

 

  C. public int addValue( int a ){// do something...}

 

  D. public int addValue( int a, int b )throws MyException {//do

something...}

 

  (bc)

 

  题目:哪些方法可以加入类Child中。

 

  此题涉及方法重载(overload),方法重写(override)以及类派生时方法重写的规则

。方法重载的规则是:一、参数列表必须不同,个数的不同完全可以,如果个数相同则参数类

型的不同不能引起歧意,例如int

和long,float和double就不能作为唯一的类型不同;二、返回值可以不同,但是不能是重载

时唯一的不同点(这点和c++中不同,c++中返回类型必须一致)。方法重写发生在类继承时,

子类可以重写一个父类中已有的方法,必须在返回类型和参数列表一样时才能说是重写,否则

就是重载,java中方法重写的一个重要而且容易被忽略的规则是重写的方法的访问权限不能比

被重写的方法的访问权限低!重写的另一个规则是重写的方法不能比被重写的方法抛弃(thro

ws)更多种类的异常,其抛弃的异常只能少,或者是其子类,不能以抛弃异常的个数来判断种

类,而应该是异常类层次结果上的种类。此题中答案a的错误就是重写的访问权限比被重写的

方法的低,而b,c都属于重载,d的错误在于比被重写的方法抛弃了更多种类的异常。

posted on 2009-10-16 11:42 李云泽 阅读(259) 评论(0)  编辑  收藏 所属分类: 面试笔试相关的SCJP认证学习


只有注册用户登录后才能发表评论。


网站导航: