第九節:Java 繼承
1 .繼承的定義
繼承可以看成是類與類之間的衍生關係。比如狗類是動物類,牧羊犬類又是狗類。於是我們可以說狗類繼承了動物類,而牧羊犬類就繼承了狗類。於是狗類就是動物類的子類(或派生類),動物類就是狗類的父類(或基類)。
所以繼承需要符合的關係是:is-a,父類更通用,子類更具體。
我們建立一個類需要它來繼承某一個類的語法:

例如我們定義了一個 Animal 類,我們在建立一個 Dog 類,我們需要它繼承 Animal 類。

下面就來練習一下吧!
我們先建立一個父類 Animal

接下來建立一個子類:

上面便是系統生成的程式碼,Dog 類繼承了父類 Animal,我們 Dog 類裡什麼都沒有寫,其實它繼承了父類 Aniamal,所以 Dog 類擁有 Aniamal 類的全部方法和屬性(除開 private 方法和屬性)。我們建立一個測試類測試一下。

為什麼需要繼承?
如果有兩個類相似,那麼它們會有許多重複的程式碼,導致後果就是程式碼量大且臃腫,後期的維護性不高。通過繼承就可以解決這個問題,將兩段程式碼中相同的部分提取出來組成一個父類,實現程式碼的複用。
繼承的特點:
子類擁有父類除private以外的所有屬性和方法
子類可以擁有自己的屬性和方法
子類可以重寫實現父類的方法
Java 中的繼承是單繼承,一個類只有一個父類
注:Java 實現多繼承的一個辦法是 implements(實現)介面。
2. 方法的重寫
雖然子類可以繼承父類的方法,但如果子類對父類的方法不滿意,想在裡面加入適合自己的一些操作時,我們就需要將方法進行重寫。並且子類在呼叫方法中,優先呼叫子類的方法。
比如上一個例子中 Animal 有bark()這個方法代表了動物叫,但是不同的動物有不同的叫法,比如狗是汪汪汪,貓是喵喵喵。
當然在方法重寫時我們需要注意,重寫的方法一定要與原父類的方法語法保持一致,比如返回值型別,引數型別及個數,和方法名都必須一致。
例如:

結果;

3 .繼承的初始化順序
我們學習了繼承後,知道在一個繼承關係中一定會有一個父類和至少一個子類,那麼在程式執行的過程中,是先為父類進行初始化,還是先呼叫的子類進行初始化的呢?
繼承的初始化順序是先初始化父類再初始化子類。
例如:


由此可知,系統先建立了父類物件,再建立了子類物件,先初始化了屬性,再呼叫了建構函式。
最後再講一個小知識。
final關鍵字可以修飾類、方法、屬性和變數
final 修飾類,則該類不允許被繼承,為最終類
final 修飾方法,則該方法不允許被覆蓋(重寫)
final 修飾屬性:則該類的屬性不會進行隱式的初始化(類的初始化屬性必須有值)或在構造方法中賦值(但只能選其一)
final 修飾變數,則該變數的值只能賦一次值,即變為常量
super關鍵字在子類內部使用,代表父類物件。
訪問父類的屬性super.屬性名
訪問父類的方法super.bark()
子類構造方法需要呼叫父類的構造方法時,在子類的構造方法體裡最前面的位置:super()
注:
繼承的特性:
子類擁有父類非private的屬性,方法。
子類可以擁有自己的屬性和方法,即子類可以對父類進行擴充套件。
子類可以用自己的方式實現父類的方法。
Java的繼承是單繼承,但是可以多重繼承,單繼承就是一個子類只能繼承一個父類,多重繼承就是,例如A類繼承B類,B類繼承C類,所以按照關係就是C類是B類的父類,B類是A類的父類,這是java繼承區別於C++繼承的一個特性。
提高了類之間的耦合性(繼承的缺點,耦合度高就會造成程式碼之間的聯絡)。
繼承關鍵字
繼承可以使用 extends 和 implements 這兩個關鍵字來實現繼承,而且所有的類都是繼承於 java.lang.Object,當一個類沒有繼承的兩個關鍵字,則預設繼承object(這個類在 java.lang 包中,所以不需要 import )祖先類。
extends關鍵字
在 Java 中,類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,所以 extends 只能繼承一個類。
implements關鍵字
使用 implements 關鍵字可以變相的使java具有多繼承的特性,使用範圍為類繼承介面的情況,可以同時繼承多個介面(介面跟介面之間採用逗號分隔)。(介面之間)
super 與 this 關鍵字
super關鍵字:我們可以通過super關鍵字來實現對父類成員的訪問,用來引用當前物件的父類。
this關鍵字:指向自己的引用。

1、為什麼使用繼承
從已有的類派生出新的類,稱為繼承。
在不同的類中也可能會有共同的特徵和動作,可以把這些共同的特徵和動作放在一個類中,讓其它類共享。
因此可以定義一個通用類,然後將其擴充套件為其它多個特定類,這些特定類繼承通用類中的特徵和動作。
繼承是 Java 中實現軟體重用的重要手段,避免重複,易於維護,易於理解。
2、父類和子類
如果類 B 從類 A 派生,或者說類 B 擴充套件自類 A,或者說類 B 繼承類 A,
則稱類 A 為"父類",也稱為超類、基類;
稱類 B 為"子類",也稱為次類、擴充套件類、派生類。
子類從它的父類中繼承可訪問的資料域和方法,也可以新增新的資料域和新的方法。
定義繼承的語法:
修飾符 class 子類名 extends 父類名
例如:Shape 類是父類,其子類可以有 Circle 類、Rectangle 類、Triangle 類,等等。
繼承的注意點:
子類不是父類的子集,子類一般比父類包含更多的資料域和方法。
父類中的 private 資料域在子類中是不可見的,因此在子類中不能直接使用它們。
繼承是為"是一個"的關係建模的,父類和其子類間必須存在"是一個"的關係,否則不能用繼承。
但也並不是所有"是一個"的關係都應該用繼承。例如,正方形是一個矩形,但不能讓 Square 類來繼承 Rectangle 類,因為正方形不能從矩形擴充套件得到任何東西。正確的繼承關係是 Square 類繼承 Shape 類
Java 只允許單一繼承(即一個子類只能有一個直接父類),C++ 可以多重繼承(即一個子類有多個直接父類)。
3、super 關鍵字
super 表示使用它的類的父類。super 可用於:
呼叫父類的構造方法;
呼叫父類的方法(子類覆蓋了父類的方法時);
訪問父類的資料域(可以這樣用但沒有必要這樣用)。
呼叫父類的構造方法語法:
super(); 或 super(引數列表);
注意:super 語句必須是子類構造方法的第一條語句。不能在子類中使用父類構造方法名來呼叫父類構造方法。 父類的構造方法不被子類繼承。呼叫父類的構造方法的唯一途徑是使用 super 關鍵字,如果子類中沒顯式呼叫,則編譯器自動將 super(); 作為子類構造方法的第一條語句。這會形成一個構造方法鏈。
靜態方法中不能使用 super 關鍵字。
呼叫父類的方法語法:
super.方法名(引數列表);
如果是繼承的方法,是沒有必要使用 super 來呼叫,直接即可呼叫。但如果子類覆蓋或重寫了父類的方法,則只有使用 super 才能在子類中呼叫父類中的被重寫的方法。
4、this 關鍵字
this 關鍵字表示當前物件。可用於:
呼叫當前類的構造方法,並且必須是方法的第一條語句。如:this(); 呼叫預設構造方法。this(引數); 呼叫帶參構造方法。
限定當前物件的資料域變數。一般用於方法內的區域性變數與物件的資料域變數同名的情況。如 this.num = num。this.num 表示當前物件的資料域變數 num,而 num 表示方法中的區域性變數。
歡迎關注微信公眾號:Java的學習之路
裡面資料非常全,從java初級到高階都有,視訊,電子書,面試寶典,簡歷模板,經典案例,原始碼分析程式設計師故事以及解決bug方法。。。。應有盡有,可以推薦大家一起學習下!!
