1. 程式人生 > >20175316盛茂淞 2018-2019-2 《Java程序設計》第5周學習總結

20175316盛茂淞 2018-2019-2 《Java程序設計》第5周學習總結

有時 關鍵字 ava 猴子 lan 被調用 允許 它的 進度

20175316盛茂淞 2018-2019-2 《Java程序設計》第5周學習總結

教材學習內容總結

第六章 接口與實現、

何謂接口

  • 接口:書上沒有明確地給出接口的定義,我理解的接口就是一段程序中可能有很多類會有共同的行為,但這些類本身並不具有任何關系,如果使用繼承的話程序架構會不合理,所以使用統一的接口表示這些類具有共同的行為
    interface
    可定義行為,例如:
public interface Swimmer{
        public abstract void swim();
    }

implements
類要操作接口,必須使用 implements 關鍵字,例如:

public abstract class Fish implements Swimmer{
}
  • 操作某接口時,對接口中定義的方法有兩種處理方式:
    1. 操作接口中定義的方法
    2. 再度將該方法標示為 abstract
      繼承與操作接口的區別:繼承會有“是一種”關系,操作接口表示“擁有行為”,但不會有“是一種”的關系
  • 多態語法合法性判斷:判斷等號右邊是不是擁有等號左邊的行為,即等號右邊的對象是不是操作了等號左邊的接口,以下這個例子就可以通過編譯:
    Swimer swimmer = new Shark();//因為 Fish 操作了 Swimmer 接口,即 Fish 擁有了 Swimmer 行為。Shark 繼承 Fish ,所以Shark 擁有 Swimmer 行為
  • 扮演語法:會操作 Swimmer 接口的不一定繼承Fish,加上扮演語法即可通過編譯,例如:
Swimmer swimmer = new Shark();
Fish fish = (Fish)swimmer;

以下的例子將會拋出 ClassCastException 錯誤:

Swimmer swimmer = new Human();//將 swimmer 參考到 Human實例
Shark shark = (Shark)swimmer;//讓 swimmer 扮演鯊魚

已經將 swimmer 參考到 Human 實例了,再讓他扮演鯊魚就會出現錯誤

  • 解決需求變更問題:我們可以定義一些擁有不同行為的接口,定義一些類作為父類,當增加新的需求的時候,可以操作接口,代表擁有接口的行為,也
    可以繼承父類,代表這個新的類“是一種”父類,原有的程序無需修改,只針對新的需求撰寫程序即可
  • 在java中,類可以操作兩個以上的接口,也就是擁有兩種以上的行為
  • 在java中,接口可以繼承自另一個接口,也就是繼承父接口行為,再在子接口中額外定義行為,例如:
public interface Diver extends Swimmer{  //接口 Diver 繼承了接口 Swimmer
    public abstract void dive();
}

接口語法細節

  • 在java中,可使用 interface 定義抽象的 行為與外觀,如接口中的方法可聲明為 public abstract ,例如:
public interface Swimmer{
    public abstract void swim();
}
  • 接口中的方法沒有操作的時候,一定要是公開抽象,可以省略 public abstract ,例如:
  public interface Swimmer{
    void swim();  //此處默認是 public abstract
}
  • 由於默認一定是 public ,在類操作接口的時候也要撰寫 public
interface Action{
    void execute();
}

class Some implements Action{
    void execute(){
    //Some 類在操作 execute() 方法時,沒有撰寫 public ,因此默認為是包權限,這等於是將 Action 中的 public 方法縮小為包權限,所以編譯失敗
    //將 Some 類的 execut() 設為public 才可通過編譯
    System.out.println("做一些服務");
    }
}

在 interface 中,只能定義 public static final的枚舉常數 ,例如:

public interface Action{
    public static final int STOP = 0;
}

如下撰寫程序時,編譯程序會自動展開為public static final

public interface Action{
    int STOP = 0;
}
  • 在接口中枚舉常數,一定要使用 = 指定值,否則編譯錯誤
  • 接口可以繼承別的接口,可以同時繼承兩個以上的接口,使用 extends 關鍵字 ,代表了繼承父接口的行為,例:
interface Action{
    void executes();
}
// 定義 Acton 為父接口
interface Some extends Action{
    void doSome();
}
interface Other extends Action{
    void doOther();
}
// Some 和 Other 接口繼承 Action 接口
public class Service implements Some,Other{
// Service 繼承 Some 和 Other 接口
    @Override
    public void execute(){
        System.out.println("execute()");
    }
// Service 重新定義 execute() 方法
    @Override
    public void doSome{
        System.out.println("doSome()");
    }
    @Override
    public void doOther{
        System.out.println("doOther()");
    }
// Service 重新定義 doSome 和 doOther 方法
}

匿名內部類

  • 某些子類或接口操作類只使用一次,不需要為這些類定義名稱,這時可使用匿名內部類
  • 語法:
new 父類()|接口(){
    //類本體操作
};
  • JDK8 之前,若要在匿名內部類中存取局部變量,則該局部變量必須是 final ,否則會發生編譯錯誤
final int[] numbers = {10,20};

enum

enum 可定義枚舉常數,但實際上 enum 定義了特殊的類,繼承自 java。lang.Enum ,編譯過後會產生 Action.class 文件,可用這個 Action 聲明類型,例如:

public class Game {
    public static void main(String[] args){
        play(Action.RIGHT);
        play(Action.UP);
    }
    
    public static void play(Action action){
        switch(action){
            case STOP:
                out.println("播放停止動畫");
                break;
            case RIGHT:
                out.println("播放向右動畫");
                break;
            case LEFT:
                out.println("播放向左動畫");
                break;
            case UP:
                out.println("播放向上動畫");
                break;
            case DOWN:
                out.println("播放向下動畫");
                break;
        }
    }
}
  • enum中列舉的常熟,實際上是 public static final ,且為枚舉類型實例,因為構造函數權限設定為 private ,只有類中才可以實例化

教材學習中的問題和解決過程

問題一

Java中的繼承和C語言中調用函數有何區別?

  • Answer
    Java語言與C語言本身就是兩種不同思維的語言。C語言是面向過程的語言,就是我們要幹一件事情,那麽一步一步逐次來做,直到完成,其中可能就要調用一些函數,被調用的函數也是過程執>行的。但是Java程序的開發思路是面向對象的,它是有一個類,這個類有屬性,有方法。我們要幹一件事的時候,就通過該類所定義的或者說是具體化的對象(Object)來調用自己的方法來完成,這裏所說的方法,也可以理解為是一個函數(類似於C語言中的),但是只不過這個方法現在是屬於這個類的,屬於這個對象的,是有“主人”的,只有通過它的“主人”才能調用它。而面向對象的Java有一個特點就是繼承,當某一個類A繼承了類B那麽類A就可以使用類B的方法了,因為A繼承了B,同樣A的對象也可以使用B的方法了。

問題二

繼承類和接口有何區別?

  • Answer:
    1.不同的修飾符修飾(interface),(extends)
    2.在面向對象編程中可以有多繼承!但是只支持接口的多繼承,不支持“繼承”的多繼承。而繼承在java中具有單根性,子類只能繼承一個父類
    3.在接口中只能定義全局常量,和抽象方法,而在繼承中可以定義屬性方法,變量,常量等。
    4.某個接口被類實現時,在類中一定要實現接口中的抽象方法,而繼承想調用那個方法就調用那個方法,毫無壓力。
    舉個有趣的例子:
    當使用繼承的時候,主要是為了不必重新開發,並且在不必了解實現細節的情況下擁有了父類我所需要的特征。
    但是很多時候,一個子類並不需要父類的所有特征,它可能只是需要其中的某些特征,但是由於通過繼承,父類所有的特征都有了,需要的和不需要的特征同時具備了。而那些子類實際上不需要用到的,有時候甚至是極力避免使用的特征也可以隨便使用,這就是繼承的副作用。特別是允許多重繼承的Java語言中,很容易引起不容易發現的錯誤。所以在java的語言中,會創造出各種規定來限制子類使用父類中的某些方法。
    如果狗的主人只是希望狗能爬比較低的樹,但是不希望它繼承尾巴可以倒掛在樹上,像猴子那樣可以飛檐走壁,以免主人管不住它。那麽狗的主人肯定不會要一只猴子繼承的狗。
    設計模式更多的強調面向接口。猴子有兩個接口,一個是爬樹,一個是尾巴倒掛。我現在只需要我的狗爬樹,但是不要它尾巴倒掛,那麽我只要我的狗實現爬樹的接口就行了。同時不會帶來像繼承猴子來帶來的尾巴倒掛的副作用。這就是接口的好處。
    Java技術發展也有好多年了,一個很明顯的趨勢就是繼承的使用越來越少,而接口的使用越來越廣泛了。其實只要稍微比較一下JDK裏面那些最早就有的類庫和最近才加進去的類庫,就可以很明顯的感覺到java技術領域的編程風格的變遷,由大量的繼承到幾乎無處不用的面向接口編程。
    接口不是替代繼承。比如說我現在就是要我的動物去爬樹,我根本就不需要知道到底是狗去爬樹還是猴子。我提取出“能爬樹”的動物去爬。這個能爬樹的動物既可以是猴子,也可以是狗。這樣不是很靈活嗎?

本周感悟

  • 經過了本章學習,我感覺自己的比上周又進步了很多,而且幾周時間,在練習的過程中我已經敲了將近兩千行代碼了,就像老師說的那樣,通過敲代碼的練習,真真切切的可以感受到自己對代碼的理解一直在上升,一開始我會抱有疑問:敲代碼不就是可以記憶的更好麽?其實不止如此,敲代碼的過程也要是一個思考的過程,我們敲代碼不是單純的敲鍵盤,腦袋也要進行思考,出現了問題要去發現問題解決問題,沒有問題也要去想想這段代碼雖然運行成功了,但是合理麽?如果合理,還有可以改進的地方麽?帶著思考去學習,進步才會越來越大,就像老師給的那道思考題——正方形可以繼承長方形麽?如果我們單純的敲代碼,我們可以敲出一個運行成功的代碼,結果也是我們想的,但是,正確答案是不可以的,那麽正確答案就需要我們自己思考,設計一個驗證的方案,不光這道思考題如此,我們以後接觸的代碼會越來越復雜,很多地方無論邏輯上還是規則上都需要進行思考。
  • 本周學習,我最大的收獲就是對代碼思考的越來越多了,不只是在敲代碼了。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一周 200/200 2/2 20/20
第二周 300/500 2/4 18/38
第三周 500/1000 3/7 22/60
第四周 300/1300 2/9 30/90
第五周 300/1600 2/10 30/120

20175316盛茂淞 2018-2019-2 《Java程序設計》第5周學習總結