20175316盛茂淞 2018-2019-2 《Java程序設計》第5周學習總結
阿新 • • 發佈:2019-04-01
有時 關鍵字 ava 猴子 lan 被調用 允許 它的 進度
20175316盛茂淞 2018-2019-2 《Java程序設計》第5周學習總結
教材學習內容總結
第六章 接口與實現、
何謂接口
- 接口:書上沒有明確地給出接口的定義,我理解的接口就是一段程序中可能有很多類會有共同的行為,但這些類本身並不具有任何關系,如果使用繼承的話程序架構會不合理,所以使用統一的接口表示這些類具有共同的行為
interface
可定義行為,例如:
public interface Swimmer{
public abstract void swim();
}
implements
類要操作接口,必須使用 implements 關鍵字,例如:
public abstract class Fish implements Swimmer{ }
- 操作某接口時,對接口中定義的方法有兩種處理方式:
- 操作接口中定義的方法
- 再度將該方法標示為 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周學習總結