201521123003《Java程序設計》第4周學習總結

1. 本章學習總結

你對於本章知識的學習總結
1.1 嘗試使用思惟導圖總結有關繼承的知識點。
參考資料:html

百度腦圖
XMindjava

1.2 使用常規方法總結其餘上課內容。app

(1)瞭解了類型轉換(cast),只能在繼承層次內進行類型轉換,將父類強制轉換成子類以前,應使用instanceof進行檢查。
(2)懂得如何運用控制可見性的4個訪問修飾符:
private -- 僅對本類可見
public -- 對全部類可見
protected -- 對本包和全部子類可見
默認 -- 沒有標明任何修飾符,通常不用,對本包可見
(3)區分覆蓋(Override)與重載(Overload)的區別。ide

2. 書面做業

Q1.註釋的應用
使用類的註釋與方法的註釋爲前面編寫的類與方法進行註釋,並在Eclipse中查看。(截圖)
函數

對圖形面積、周長求和的實驗代碼作了簡單的註釋
類的註釋
工具

方法的註釋
學習

Q2.面向對象設計(大做業1,很是重要)
2.1 將在網上商城購物或者在班級博客進行學習這一過程,描述成一個故事。(不得少於50字,參考QQ羣中PPT的範例)
1.進入網上購物商城網站
測試

2.進入登陸頁面,登入帳號
flex

3.查找所要購買的商品,並在相應界面進行選擇
網站

4.進入對應商品查看商品屬性,加入購物車

5.查看購物車進行確認

6.結算購買商品

2.2 經過這個故事咱們能發現誰在用這個系統,系統中包含的類及其屬性方法,類與類之間的關係。嘗試找到這些類與屬性,並使用思惟導圖描述類、屬性、方法及類與類之間的關係。
參考資料:**
UML類圖
面向對象案例-借款者姓名地址.zip

Q3.ManagerTest.zip代碼分析
分析ManagerTest.zip中的代碼,回答幾個問題:

3.1 在本例中哪裏體現了使用繼承實現代碼複用?回答時要具體到哪一個方法、哪一個屬性。

class Manager extends Employee //Manager類繼承父類Employee類,得到父類的屬性和方法
{
   /**
    * @param n the employee's name
    * @param s the salary
    * @param year the hire year
    * @param month the hire month
    * @param day the hire day
    */
   public Manager(String n, double s, int year, int month, int day)
   {
      super(n, s, year, month, day);//調用父類的有參構造函數來完成對子類的初始化
      bonus = 0;
   }

   public double getSalary()
   {
      double baseSalary = super.getSalary();//調用父類的getSalary()方法
      return baseSalary + bonus;
   }

   public void setBonus(double b)
   {
      bonus = b;
   }

   private double bonus;
}

如上代碼註釋上所述,Manager類繼承父類Employee類,得到父類的屬性和方法,父類屬性中的name,salary,hireday則無需從新定義,還利用關鍵字super調用了Employee類的構造函數對子類的對象進行初始化,以及調用了getSalary()方法。

3.2Employee類及其子類Manager都有getSalary方法,那怎麼區分這兩個方法呢?

若是父類和子類都有相同的方法名,可使用super關鍵字調用父類的方法,使用super能夠訪問父類被子類隱藏的同名的成員。super.getSalary()使用的是父類中的方法,而getSalary()則是子類的方法。

3.3 文件第26行e.getSalary(),究竟是調用Manager類的getSalary方法仍是Employee類的getSalary方法。

運行代碼獲得的結果如上圖所示,源代碼中Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);staff[0]=boss的屬性是Manager類的,因此調用的是Manager類中getSalary()方法,在Manager的getSalary()中繼承了它的父類Employee的getSalary()方法;staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);staff]1]和staff[2]的屬性是Employee類的,因此調用的是Employee類中的getSalary方法。

3.4 Manager類的構造函數使用super調用父類的構造函數實現了代碼複用,你以爲這樣的有什麼好處?爲何不把父類構造函數中的相關代碼複製粘貼到Manager的構造函數中,這樣看起來不是更直觀嗎?

雖然在每一個類中複製相關的代碼看起來很直觀,可是代碼量很是大,同時給代碼的維護上也會帶來極大的不便,例如代碼中的name,salary,hireday要進行修改,就要在每個類中進行修改,這樣豈不是費時費力。若是使用了繼承的思想來實現代碼,用super調用父類的構造函數,在修改時只需在父類上進行相應的修改,這樣大大方便了代碼的維護,而且減小了代碼的冗餘度,提升了代碼的複用性,使代碼看起來更加簡潔,何樂而不爲呢。

Q4.Object類
4.1 編寫一個Fruit類及屬性String name,如沒有extends自任何類。使用System.out.println(new Fruit());是調用Fruit的什麼方法呢?該方法的代碼是從哪來的?嘗試分析這些代碼實現了什麼功能?

class Fruit{
    private String name;
}
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Fruit());
    }
}

運行結果以下:

object的toString()方法通常就是打印某個對象的「地址」,即對象的所屬類以及該對象的哈希值
參考文章

在Java中,全部的對象都是繼承自Object,天然繼承了toString方法,在當使用System,out.println()裏面爲一個對象的引用時,自動調用toString方法講對象打印出來。若是重寫了tostring方法則調用重寫的toString 方法。
查看println的源代碼便可知道toString方法的來源

4.2 若是爲Fruit類添加了toString()方法,那麼使用System.out.println(new Fruit());調用了新增的toString方法。那麼其父類中的toString方法的代碼就沒有了嗎?若是同時想要複用其父類的toString方法,要怎麼操做?(使用代碼演示)
·調用新增的toString方法

class Fruit{
    private String name;

    @Override
    public String toString() {
        return "Fruit [name=" + name + "]";
    }  //新增的toString方法
    
}
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Fruit());
    }
}

運行結果:

·父類Object中的toString方法固然還在,只需用關鍵字super調用便可。

class Fruit{
    private String name;

    @Override
    public String toString() {
        return "Fruit [name=" + name + "]"+"\n"+super.toString();
    }  //新增的toString方法
    
}
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Fruit());
    }
}

運行結果以下:

4.3 Fruit類還繼承了Object類的eqauls方法。嘗試分析其功能?本身編寫一個equals方法覆蓋父類的相應方法,功能爲當兩個Fruit對象name相同時(忽略大小寫),那麼返回true。(使用代碼證實你本身覆蓋的eqauls方法是正確的)

equals()是對兩個對象的地址值進行的比較(即比較引用是否相同),相同返回true,不一樣返回false。
Object類的eqauls方法,查看源代碼以下圖

本身編寫equals方法覆蓋父類,能夠利用自動生成,只需對忽略大小寫上進行修改便可,代碼以下:

package Q4;

class Fruit{
    private String name;
    public Fruit(String name){
        this.name=name;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Fruit other = (Fruit) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equalsIgnoreCase(other.name)) //java.lang.String.equalsIgnoreCase()方法比較字符串到另外一個字符串,忽略大小寫因素。
            return false;
        return true;
    }
}
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //System.out.println(new Fruit());
        Fruit a=new Fruit("Apple");
        Fruit b=new Fruit("apple");
        System.out.println(a.equals(b));

    }
}

運行結果以下:

4.4 在4.3的基礎上使用ArrayList fruitList存儲多個fruit,要求若是fruitList中已有的fruit就再也不添加,沒有的就添加進去。請編寫相關測試代碼。並分析ArrayList的contatins方法是如何實現其功能的?

import java.util.ArrayList;
class Fruit{
    private String name;
    public Fruit(String name){
        this.name=name;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Fruit other = (Fruit) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equalsIgnoreCase(other.name)) //java.lang.String.equalsIgnoreCase()方法比較字符串到另外一個字符串,忽略大小寫因素。
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Fruit [name=" + name + "]";
    }
    
}
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //System.out.println(new Fruit());
        Fruit a=new Fruit("apple");
        Fruit b=new Fruit("Apple");
        Fruit c=new Fruit("banana");
        ArrayList<Fruit> fruitList=new ArrayList<Fruit>();
        fruitList.add(b);
        if(!fruitList.contains(a)){
            fruitList.add(a);
        }
        if(!fruitList.contains(c)){
            fruitList.add(c);
        }
        System.out.println(fruitList);
    }
}

運行結果以下:

ArrayList的contatins方法,從頭至尾檢索字符串,含有字符串的子串就返回true,不然返回false,能夠查看源代碼,以下圖

Q5.代碼閱讀:PersonTest.java(abstract、多態)
5.1 畫出類的繼承關係

5.2 讀懂main函數,將本身推測的出代碼運行結果與真正運行結果進行比較。嘗試分析緣由
運行結果以下:

Person類是一個抽象類,沒有實例對象,Student類,Employee類,Manager類和Programmer類的toString()方法是利用super關鍵字調用父類Person類的toString()方法,得出運行結果,Manager類和Programmer類是繼承Employee類的,Employee類是繼承Person類的。

5.3 子類中裏面使用了super構造函數,做用是什麼?若是將子類中的super構造函數去掉,行不行?

做用:調用父類的構造函數。
不能去掉,去掉後編譯器會調用父類無參構造函數,而PersonTest.java中沒有無參構造函數,會出現編譯出錯的問題。

5.4 PersonTest.java中的代碼哪裏體現了多態?你以爲多態有什麼好處?多態和繼承有什麼關係嗎?
參考文件:PersonTest.java

多態性:相同的形態,不一樣的行爲(不一樣的定義)
相同的方法名,不一樣的實現
父類類型變量能夠引用子類對象
多態的好處:
多態的好處:
1)可替換性(substitutability):多態對已存在代碼具備可替換性。例如,多態對圓Circle類工做,對其餘任何圓形幾何體,如圓環,也一樣工做。
2)可擴充性(extensibility):多態對代碼具備可擴充性。增長新的子類不影響已存在類的多態性、繼承性,以及其餘特性的運行和操做。實際上新加子類更容易得到多態功能。例如,在實現了圓錐、半圓錐以及半球體的多態基礎上,很容易增添球體類的多態性。
3)接口性(interface-ability):多 態是超類經過方法簽名,向子類提供了一個共同接口,由子類來完善或者覆蓋它而實現的。如圖8.3 所示。圖中超類Shape規定了兩個實現多態的接口方法,computeArea()以及computeVolume()。子類,如Circle和 Sphere爲了實現多態,完善或者覆蓋這兩個接口方法。
4)靈活性(flexibility):它在應用中體現了靈活多樣的操做,提升了使用效率。
5)簡化性(simplicity):多態簡化對應用軟件的代碼編寫和修改過程,尤爲在處理大量對象的運算和操做時,這個特色尤其突出和重要。
參考文章
多態和繼承的關係:
繼承:子類繼承父類中因此的屬性和方法,可是對於private的屬相和方法,因爲這個是父類的隱私,因此子類雖然是繼承了,可是沒有能夠訪問這些屬性和方法的引用,因此至關於沒有繼承到。
多態:就是父類引用能夠持有子類對象。這時候只能調用父類中的方法,而子類中特有方法是沒法訪問的,由於這個時候(編譯時)你把他看做父類對象的緣由,可是到了運行的時候,編譯器就會發現這個父類引用中原來是一個子類的對像,因此若是父類和子類中有相同的方法時,調用的會是子類中的方法,而不是父類的。

3. PTA實驗總結及碼雲上代碼提交記錄

3.1本週Commit歷史截圖

在碼雲的項目中,依次選擇「統計-Commits歷史-設置時間段」,而後搜索並截圖,以下圖所示

3.2 實驗總結

實驗碰到的問題、思考、收穫與解決方案

實驗第四題實際上是對第三題的稍加改造,利用繼承和多態的方法減小代碼的冗餘度,還用了抽象類,運用了abstract關鍵字。 實驗第五題主要是利用工具欄中的Source自動生成函數,遇到的問題是equals()函數的編寫。 實驗第六題更加熟練地使用super複用Person類的相關有參構造函數,利用Collections.sort()來進行排序。主要遇到的問題仍是equals()函數沒有考慮周全,以及ArrayList的運用。

相關文章
相關標籤/搜索