第12章 繼承與接口

12.3 this

Java程序員面試寶典 作者:歐立奇、朱梅、段韜 編著


  面試?yán)}1:下面程序的結(jié)果是什么?[Trend公司面試題]

  class Tester

{

int var;

Tester(double var)

{

      this.var = (int)var;

     

}

 

Tester(int var)

{

      this("hello");

}

 

Tester(String s)

{

      this();

    System.out.println(s);

}

Tester()

{

    System.out.println("good-bye");

}

 

public static void main(String[] args)

{

      Tester t = new Tester(5);

}

}

  答案:

  good-bye
  hello

  擴(kuò)展知識(shí)(變量的內(nèi)存分配情況)

  在Java中有兩個(gè)非常特殊的變量:this和super,這兩個(gè)變量在使用前都是不需要聲明的。this變量使用在一個(gè)成員函數(shù)的內(nèi)部,指向當(dāng)前對(duì)象,當(dāng)前對(duì)象指的是調(diào)用當(dāng)前正在執(zhí)行方法的那個(gè)對(duì)象。super變量是直接指向超類的構(gòu)造函數(shù),用來(lái)引用超類中的變量和方法。因此它們都是非常有用的變量。下面介紹一下this的使用方法。

  先看下面的一段代碼。

  class PersonInformation

  {

  String name,gender,nationality,address;

  int age;

  void PersonInformation(String p_name,String p_gender,String

  p_nationality,String p_address,int p_age)

  {

  name=p_name;

  gender=p_gender;

  nationality=p_nationality;

  address=p_address;

  age=p_age;

  }

  }

  在PersonInformation()函數(shù)中這個(gè)對(duì)象的方法提示可以直接訪問對(duì)象的成員變量,而且在同一個(gè)范圍中,定義兩個(gè)相同的名字的局部變量是不允許的。如果確實(shí)想使類的成員變量與方法的參數(shù)或方法自己定義的局部變量同名的話,就需要想一種方法使成員變量與跟它同名的方法參數(shù)或局部變量區(qū)分開來(lái),這就要使用到this變量。下面改寫一下上面的代碼,使PersonInformation類的構(gòu)造函數(shù)的每個(gè)參數(shù)都有與對(duì)象成員變量相同的名字,而成員變量的初值由參數(shù)給出。

  class PersonInformation

  {

  String name,gender,nationality,address;

  int age;

  void PersonInformation(String name,String gender,String

  nationality,String address,int age)

  {

  this.name=name;

  this.gender=gender;

  this.nationality=nationality;

  this.address=address;

  this.age=age;

  }

  }

  從上例中可以看出,該構(gòu)造函數(shù)中必須使用this。this在方法體中用來(lái)指向引用當(dāng)前正在執(zhí)行方法的那個(gè)對(duì)象實(shí)例。this變量的類型總是為包含前執(zhí)行方法的類。在上例中,我們要區(qū)別參數(shù)name和成員變量name,寫成name=name顯然是不允許的。在參數(shù)或局部變量名與類成員變量名相同的時(shí)候,由于參數(shù)或局部變量的優(yōu)先級(jí)高,這樣在方法體中參數(shù)名或局部變量名將隱藏同名的成員變量,因此,為了指明成員變量,必須使用this顯式地指明當(dāng)前對(duì)象。

  有時(shí)候會(huì)遇到這種情況,全面地訪問當(dāng)前對(duì)象,而不是訪問某一個(gè)個(gè)別的實(shí)例對(duì)象,此時(shí)也可以使用this,并利用Java中的toString()方法(它能夠返回一個(gè)描述這個(gè)對(duì)象的字符串)。如果把任何一個(gè)對(duì)象傳遞到System.out.println方法中,這個(gè)方法調(diào)用這個(gè)對(duì)象的toString方法,并打印出結(jié)果字符串,所以,可以用System.out.println(this)方法來(lái)打印出固有參數(shù)的當(dāng)前狀態(tài)。

  this還有一個(gè)用法,就是構(gòu)造函數(shù)的第一個(gè)語(yǔ)句,它的形式是this(參數(shù)表),這個(gè)構(gòu)造函數(shù)就會(huì)調(diào)用同一個(gè)類的另一個(gè)相對(duì)的構(gòu)造函數(shù)。請(qǐng)看下面的例子。

  class UserInfo

  {

  public UserInfo(String name)

  {

  this(name,aNewSerialNumber);

  }

  public Userinfo(String name,int number)

  {

  userName=name;

  userNumber=number;

  }}

  如果調(diào)用UserInfor newinfotable = new UserInfo("Wayne Zheng"),就會(huì)自動(dòng)調(diào)用UserInfo(String name,int number)構(gòu)造函數(shù)。

  可見,熟練掌握this在Java程序設(shè)計(jì)過(guò)程中是非常重要的。

  面試?yán)}2:以下代碼的運(yùn)行結(jié)果是   。[Advantech公司2005年12月面試題]

  class Base{

  int i;

  Base(){

  add(1);

  System.out.println(i);

  }

  void add(int v){

  i+=v;

  System.out.println(i);

  }

  void print(){

  System.out.println(i);

  }}class MyBase extends Base{

  MyBase(){

  add(2);

  }

  void add(int v){

  i+=v*2;

  System.out.println(i);

  }}public class TestClu {

  public static void main(String[] args) {

  go(new MyBase());

  //System.out.println();

  }

  static void go(Base b){

  b.add(8);

  //b.print();

  }}

  A.12   B.11   C.22   D.21

  解析:

  程序流程是這樣的:在主函數(shù)中,首先執(zhí)行new MyBase(),在這個(gè)過(guò)程中,子類會(huì)首先調(diào)用父類的構(gòu)造函數(shù);在父類的構(gòu)造函數(shù)Base()中執(zhí)行add()方法。這里需要注意,這個(gè)add方法由于是在新建MyBase對(duì)象時(shí)調(diào)用的,將會(huì)首先查找MyBase類中是否有此方法。所以,Base()函數(shù)中的add(1)實(shí)際上是:

   void add(int v)

  { 

  i+=v*2;      System.out.println(i); 

  }

  此時(shí)i的值即為2。在打印兩個(gè)2之后,父類構(gòu)造函數(shù)執(zhí)行完畢,執(zhí)行子類的構(gòu)造函數(shù),即MyBase(),這里的add(2)當(dāng)然也是子類的。i的值就變?yōu)榱?。

  最后執(zhí)行g(shù)o函數(shù),i即為22。
  答案:C


上一章目錄下一章

Copyright ? 讀書網(wǎng) ranfinancial.com 2005-2020, All Rights Reserved.
鄂ICP備15019699號(hào) 鄂公網(wǎng)安備 42010302001612號(hào)