Java面向物件(三)—— 繼承
阿新 • • 發佈:2018-11-25
標籤: java 繼承 抽象類 this super abstract
概述
多個類中存在相同的屬性和行為的時候,將這些內容抽取到單獨一個類中,那麼多個類無需在定義這些屬性和行為,只要繼承那個類即可。
- 多個類可以稱為子類,單獨這個類稱為父類或者超類。
- 子類可以直接訪問父類中的菲斯有的屬性和行為。
- 通過 extends 關鍵字讓類與類之間產生繼承關係。
- class SubDemo extends Demo{}
- 繼承的出現提高了程式碼的複用性
- 整合的出現讓類與類之間產生了關係,提供了多型的前提。
繼承的特點
- java只支援單繼承,不支援多繼承
- 一個類只能有一個父類,不可以有過個父類
- java支援多層繼承(繼承體系)
- 定義繼承需要注意:
- 不要僅為了獲取其他類中某個功能而去繼承
- 類與類之間要有所屬(“is a”)關係,xx1是xx2的一種
class ClassDemo1{ public static void main(String[] args){ Dog d = new Dog(); d.color = "white";//雖然在Dog類中並未定義color,但是由於繼承,並不影響賦值 System.out.println(d.color); } } class Animal{ String color; int weight; } /** *建立Dog類,繼承Animal */ class Dog extends Animal{ }
說道繼承,不得不說的兩個關鍵詞就是this和super
上一篇中我們說了建構函式中傳參的方式,但是如果引數是這樣的形式呢?
class ClassDemo1{ public static void main(String[] args){ Dog d2 = new Dog("white"); System.out.println(d2.color); } } class Dog{ //成員屬性 public String color; public int age; //建構函式 //空構造 public Dog(){ } //只有一個引數的建構函式 public Dog(String color){ color = color;//******************請注意這裡******************* } }
編譯一下,ok通過,然後執行,輸出是:
D:\JAVA\java3>java ClassDemo1
null
為什麼呢?明明在主函式中傳了值“white”了啊,這裡為什麼是null呢?問題就出在了 color = color 這裡,這裡兩個變數名一樣,說簡單點,就是把電腦整懵逼了,那為了避免歧義,這時候就需要this關鍵詞了
把它改為 this.color = color 就可以了。因為this代表的是本類物件的引用,如此一來就不會產生歧義了,再次執行,結果就輸出了white。
類似的問題也出現在繼承中,子類想引用父類的建構函式怎麼辦?,ok,super就是來做這個的
super.xxx
- 訪問超類的成員
super()
- 訪問超類的建構函式
- 必須是第一行程式碼
- 建構函式的首行,要麼是this(),要麼是super(),預設是super()
super和this對比
super和this都可以看成是類中內建的成員變數,其中this是指向物件自身的引用,而super是指向超類物件中的一個引用。
注:必須寫第一行的是super(),它呼叫的是建構函式;而super.xxx,它是一個引用,是一個指向父類物件的一個引用,不用必須放在第一行。
函式的覆蓋
什麼是函式的覆蓋?就是overwrite,也叫重寫、複寫,概念是:子類中出現與父類一模一樣的方法時,會出現覆蓋操作,也稱為重寫或者複寫。
注意,父類中的private私有方法不可以被覆蓋。在子類覆蓋方法中,繼續使用被覆蓋的方法可以通過 super.函式名 來獲取。
覆蓋的注意事項:
- 覆蓋時,子類方法許可權一定要大於等於父類方法許可權
- 靜態覆蓋靜態,非靜態覆蓋非靜態,靜態性約束保持一致
繼承的時候許可權可以放大,但是不可以縮小
覆蓋的應用
當子類需要父類的功能,而功能主體子類有自己特有內同時,可以複寫父類中的方法,這樣,既沿襲了父類的功能,有定義了子類特有的內容。
始終記住一句話:任何物件的建立都意味著整個家族樹的建立
子類例項化的過程
- 子類中所有的建構函式預設都會訪問父類中空引數的建構函式,因為每一個建構函式的第一行都有一條預設的語句super();
- 子類會具備父類中的資料,所以要先明確父類是如何對這些資料初始化的
- 當父類中沒有空引數的建構函式時,子類的建構函式必須通過this或者super語句指定要訪問的建構函式。
final關鍵字
- final 可以修飾類、方法、變數。如果修飾類,不能被繼承。(斷子絕孫)
- final 修飾的方法不可以被覆蓋
- final 如果修飾變數,同樣不能被修改,只是最初可以賦值一次,也叫常量(不能發生變化),但是可以被呼叫
內部類
- 1.定義在類內部的類成為內部類
- 2.內部類可以在類成員位置上,編譯時產生的類:外部類$內部類名,例如:Benz$Engine.class
- 3.內部類還可以在方法內定義,編譯時產生的類:Benz$1Engine.class
- 4.內部類訪問區域性變數時,不能區域性變數進行重新賦值,java8不要求必須給區域性變數使用final修飾
抽象類 abstract
抽象定義:抽象就是從多個事物中共性的,本質的內容抽取出來
抽象類:Java中可以定義沒有方法體的方法,該方法的具體實現由子類完成,該方法稱為抽象方法,包含抽象方法的類就是抽象類。
抽象方法的由來:多個物件都具備相同的功能,但是功能具體內容有所不同,那麼在抽取過程中,只抽取了功能定義,並未抽取功能主體,那麼只有功能宣告,沒有功能主體的方法稱為抽象方法。例如:貓和狗都有吼叫的方法,所以抽象出來的動物雖然有吼叫功能,但是並不明確吼叫的細節。
抽象類的特點
- 抽象類和抽象方法必須用abstract關鍵字來修飾
- 抽象方法只有方法宣告,沒有方法體,定義在抽象類中。格式:修飾符 abstract 返回值型別 函式名(引數列表);
抽象類不可以被例項化,也就是不可以用new建立物件。因為抽象類是具體事物抽出來的,本身就不是具體的,沒有對應的例項,比如犬科是一個抽象的概念,真正存在的是狼和狗。而且抽象類即使建立了物件,呼叫抽象方法也沒有意義。
注意:
- 1.抽象方法:沒有函式體的方法就是抽象方法,必須用abstract修飾
- 抽象方法必須在抽象類中
- 抽象類就像是一個不全的圖紙,是不能例項化的
- 格式:修飾符 abstract 返回值 函式名(引數列表...);
- 抽象類有建構函式
2.非法修飾組合
final + abstract
private + abstract
private + final (沒有意義)