1. 程式人生 > >Java 習題4 答案及解析

Java 習題4 答案及解析

問答題

(1)面嚮物件語言有哪三個特性?
(2)類名應當遵守怎樣的程式設計風格?
(3)變數和方法的名字應當遵守怎樣的程式設計風格?
(4)類體內容中宣告成員變數是為了體現物件的屬性還是行為?
(5)類體中定義的非構造方法是為了體現物件的屬性還是行為?
(6)什麼時候使用構造方法?構造方法有型別嗎?
(7)類中的例項變數在什麼時候會被分配記憶體空間?
(8)什麼叫方法的過載?構造方法可以過載嗎?
(9)類中的例項方法可以操作類變數(static變數)嗎?類方法(static方法)可以操作例項變數嗎?
(10)類中的例項方法可以用類名直接呼叫嗎?
(11)簡述類變數和例項變數的區別。
(12)this關鍵字代表什麼?this可以出現在類方法中嗎?

問答題解析

1.封裝、繼承和多型。
2.當類名由幾個單詞複合而成時,每個單詞的首字母使用大寫。
3.名字的首單詞的首字母使用小寫,如果變數的名字由多個單片語成,從第2個單詞開始的其他單詞的首字母使用大寫。
4.屬性。
5.行為。
6.用類建立物件時。沒有型別。
7.用類建立物件時。
8.一個類中可以有多個方法具有相同的名字,但這些方法的引數必須不同,即是引數的個數不同,或者是引數的型別不同。可以。
9.可以。不可以。
10.不可以。
11.一個類通過使用new運算子可以建立多個不同的物件,不同的物件的例項變數將被分配不同的記憶體空間。所有物件的類變數都分配給相同的一處記憶體,物件共享類變數。
12.代表呼叫當前方法的物件。不可以。

選擇題

(1) 下列哪個敘述是正確的?
A. Java應用程式由若干個類所構成,這些類必須在一個原始檔中。
B. Java應用程式由若干個類所構成,這些類可以在一個原始檔中,也可以分佈在若干個原始檔中,其中必須有一個原始檔含有主類。
C. Java原始檔必須含有主類。
D. Java原始檔如果含有主類,主類必須是public類。

(2) 下列哪個敘述是正確的?
A. 成員變數的名字不可以和區域性變數的名字相同。
B. 方法的引數的名字可以和方法中宣告的區域性變數的名字相同。
C. 成員變數沒有預設值。
D 區域性變數沒有預設值.。

(3) 對於下列Hello類,哪個敘述是正確的?
A. Hello類有兩個構造方法。
B. Hello類的int Hello()方法是錯誤的方法。
C. Hello類沒有構造方法。
D. Hello無法通過編譯,因為其中的hello方法的方法頭是錯誤的(沒有型別)

Java
class Hello{
    Hello (int m){
    }
    int Hello(){
        return 20;
    }
    hello(){
    }
}

(4)對於下列Dog類,哪個敘述是錯誤的?
A. Dog(int m)與Dog(double m)是互為過載的構造方法。
B. int Dog(int m)與void Dog(double m)是互為過載的非構造方法。
C. Dog類只有兩個構造方法,而且沒有無引數的構造方法。
D. Dog類有三個構造方法。

Java
class Dog{
    Dog(int m){
    }
    Dog(int double m){
    }
    int Dog(int m){
        return 23;
    }
    void Dog(double m){
    }
}

(5) 下列哪些類宣告是錯誤的?
A. class A
B. public class A
C. protected class A
D. private class A

(6) 下列A類中【程式碼1】~【程式碼5】哪些是錯誤的?

Java
class Tom{
    private int x = 120;
    protected int y = 20;
    int z = 11;
    private void f(){
        x = 200;
        System.out.println(x);
    }
    void g(){
    x = 200;
    System.out.println(x);
    }
}
public class A{
  public static void main(String args[]){
      Tom tom = new Tom();   
      tom.x = 22;             //【程式碼1】
      tom.y = 33;             //【程式碼2】
      tom.z = 55;             //【程式碼3】
      tom.f();                //【程式碼4】
      tom.g();                //【程式碼5】

(7) 下列E類的類體中哪些【程式碼】是錯誤的?

Java
classE{
    int x;
    long y = x;
    public void f(int n){
    int m;
    int t = n+m;
    }
}

選擇題解析

1.B
C選項中一個原始檔可以沒有主類,但在一個應用程式(工程)下必須由一個主類
D選項如果若干原始檔在同一個包下,主類可以不加public修飾。

2.D
B選項如果相同,那麼在方法內賦值操作就會混亂。
C選項成員變數都是有預設值的比如int 是0 double 是0.0 String 是null。而區域性變數是沒有預設值的,所以在使用之前必須要進行初始化。

3.D
Hello只有一個構造方法,構造方法是沒有型別的,構造方法名必須和類名相同,故hello()不是構造方法,但他又沒有型別,不符合普通方法的規定,所以編譯會發生錯誤。

4.D
方法過載要求方法名相同,引數列表不同,可以是引數個數或者型別不同。構造方法也是可以過載的。Dog類有兩個構造方法(不帶型別的),而後兩個方法是互為過載的非構造方法。

5.CD
類只能用public 修飾或者預設(友好)

6.【程式碼1】【程式碼4】
Tom類中的成員變數x是私有變數,不能直接使用物件呼叫。
f是私有方法,也不能直接使用物件呼叫
protect允許在同一個包中或者是子類呼叫

7.【程式碼4】
m是區域性變數,沒有預設值,所以在沒有初始化的前提下使用會報錯。

閱讀程式

(1) 說出下列E類中【程式碼1】~【程式碼3】的輸出結果。

Java
class Fish{
    int weight = 1;
}
class Lake{
    Fish fish;
    void setFish(Fish s){
        fish = s;
    }
    void foodFish(int m){
        fish.weight=fish.weight + m;
    }
}
public class E{
    public static void main(String args[]){
        Fish redFish = new Fish();
        System.out.println(redFish.weight);//【程式碼1】
        Lake lake = new Lake();
        lake.setFish(redFish);
        lake.foodFish(120);
        System.out.println(redFish.weight);//【程式碼2】
        System.out.prihtln(lake.fish.weight);//【程式碼3】
    }
}

(2)請說出A類中System.out.println的輸出結果

Java
calss B{
    int x = 100, y = 200;
    public void setX(int x){
        x = x;
    }
    public void setY(int y){
        this.y=y;
    }
    public int getXYSum(){
        return x+y;
    }
}
public class A{
    public static void main(String args[]){
        B b = new B();
        b.setX(-100);
        b.setY(-200);
        System.out.println("sum="+b.getXYSum());
    }
}

(3)請說出A類中System.out.println的結果。

Java
class B{
    int n;
    static int sum = 0;
    void setN(int n){
        this.n = n;
    }
    int getSum(){
        for(int i=1;i<=n;i++)
            sum=sum+i;
        return sum;
    }
}
public class A{
    public static void main(String args[]){
    B b1 = new B(),b2=new B();
    b1.setN(3);
    b2.setN(5);
    int s1 = b1.getSum();
    int s2 = b2.getSum();
    System.out.println(s1+s2);

(4)請說出E類中【程式碼1】和【程式碼2】的輸出結果。

Java
class A{
    double f(int x,double y){
        return x+y;
    }
    int f(int x,int y){
        return x*y;
    }
}
public class E{
    public static void main(String args[]){
        A a = new A();
        System.out.println(a.f(10,10));//【程式碼1】
        System.out.println(a.f(10,10.0));//【程式碼2】
    }
}

閱讀程式題解析

1.【程式碼1】:1,【程式碼2】:121,【程式碼3】:121。
redFish物件是Fish類的例項,所以具有Fish類的屬性,輸出的weight是1。
lake.setFish方法傳遞的是redFish物件,將redFish物件賦值給Lake中的fish物件,那麼二者就具有了相同的引用,從而具有完全相同的變數。那麼呼叫lake.foodFish(120)時,lake物件中的fish物件的weight就變成了121,而redFish和fish的引用相同,其變數也相同,所以redFish中的weight也同樣變成了121。

2.sum=-100
這道題涉及了this關鍵字的用法。
主類中聲明瞭B類的物件先呼叫setX方法傳遞引數為-100,但在這個方法體中的語句為x=x,等號右邊的x是傳遞進的引數,而等號左邊的x同樣也指這個引數,所以相當於把引數的值賦值給本身,是沒有任何意義的。
而呼叫setY方法,等號左邊是this.y指的就是當前類下的成員變數y,所以此時成員變數y被賦值為-200,返回x+y的和就為-100。

3.27
這道題考察類變數(static變數)
無論一個類例項了多少個物件,他們都共享類中的類變數。b1中的n是3,b2中的n是5,呼叫b1.getSum求和後得到的結果是1+2+3=6賦值給s1,由於sum是類變數,所以b2中的sum也是6,再呼叫b2.getsum求和,就是6+1+2+3+4+5=21賦值給了s2,此時b1中的sum也變成了21,最後輸出s1+s2的值就為6+21=27。

4.【程式碼1】100 【程式碼2】20.0
這道題考察方法過載,方法過載要求方法名必須相同,引數列表不同(引數的個數不同或者是引數型別不同),【程式碼1】傳遞的引數是兩個int變數10和10,那麼與int f(int x,int y)方法匹配,輸出結果100,【程式碼2】傳遞的引數是int 10和double 10.0,和double f(int x, double y)匹配,輸出結果是20.0注意不能寫成20,返回的是double型別。

程式設計題

用類描述計算機中CPU的速度和硬碟的容量,要求Java應用程式由4個類,名字分別是PC、CPU、HardDisk、和Test,其中Test是主類。

  • PC類與CPU和HardDisk類關聯的UML圖
    其中,CPU類要求getSpeed()返回speed的值,要求setSpeed(int m)方法將引數m的值賦值給speed;HardDisk類要求getAmount()返回amount的值,要求setAmount(int m)方法將引數m的值賦值給amount;PC類要求setCPU(CPU c)將引數c的值賦值給CPU,要求setHardDisk(HardDisk h)方法將引數h的值賦值給HD,要求show()方法能顯示CPU的速度和硬碟的容量。
  • 主類Test的要求
    (1)main方法中建立一個CPU物件cpu,cpu將自己的speed設定為2200.
    (2)main方法中建立一個HardDisk物件disk,disk將自己的amount設定為200。
    (3)main方法中建立一個PC物件pc。
    (4)pc呼叫setCPU(CPU c)方法,呼叫時實參是cpu。
    (5)pc呼叫setHardDisk(HardDisk h)方法,呼叫時實參是disk。
    (6)pc呼叫show方法。
    這裡寫圖片描述
Java
public class CPU{
    int speed;
    int getSpeed(){
        return speed;
    }
    public void setSpeed(int speed){
        this.speed = speed;
    }
}
public class HardDisk{
    int amount;
    int getAmount(){
        return amount;
    }
    public void setAmount(int amount){
        this.amount = amount;
    }
}
public class PC{
    CPU cpu;
    HardDisk HD;
    void setCPU(CPU cpu){
        this.cpu = cpu;
    }
    void setHardDisk(HardDisk HD){
        this.HD = HD;
    }
    void show(){
        System.out.println("CPU速度:"+cpu.getSpeed());
        System.out.println("硬碟容量"+HD.getAmount());
    }
}
public class Test{
    public static void main(String args[]){
        CPU cpu = new CPU();
        HardDisk HD = new HardDisk();
        cpu.setSpeed(2200);
        HD.setAmount(200);
        PC pc = new PC();
        pc.setCPU(cpu);
        pc.setHardDisk(HD);
        pc.show();
    }
}