繼承就是子類繼承父類的特徵和行爲,使得子類對象(實例)具備父類的實例域和方法,或子類從父類繼承方法,使得子類具備父類相同的行爲。java
關鍵字 extends 代表正在構造的新類派生於一個已存在的類。ide
public class Employee { private String name; private double salary; private Date hireDay; public Employee(String n, double s, int year, int month, int day) { name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month, day); hireDay = calendar.getTime(); } public String getName() { return name; } //more method ...... }
儘管 Employee 類是一個超類,但並非由於它位於子類之上或者擁有比子類更多的功能。偏偏相反,子類比超類擁有的功能更加豐富。在 Manager 類中,增長了一個用於存儲獎金信息的域,以及一個用於設置這個域的方法:this
public class Manager extends Employee{//extends繼承Employee類 ... private double bonus; public void setBonus(double bonus) { this.bonus = bonus; } }
然而,儘管在 Manager 類中沒有顯式地定義 getName 和 getHireDay 等方法,但屬於 Manager 類的對象卻可使用它們,這是由於 Manager 類自動地繼承了超類 Employee 中的這些方法。一樣,從超類中還繼承了 name、salary 和 hireDay 這 3 個域。這樣一來,每一個 Manager 類對象就包含了4個域:name、salary、hireDay 和 bonus。編碼
在經過擴展超類定義子類的時候,僅須要指出子類與超類的不一樣之處。所以在設計類的時候,應該將通用的方法放到超類中,而將具 有特點用途的方法放在子類中,這種將通用的功能放到超類的作法,在面向對象程序設計中十分廣泛。
然而,超類中的有些方法對子類 Manager 並不必定適用。例如,在 Manager 類中的 getSalary 方法應該返回薪水和獎金的總和。爲此,須要提供一個新的方法來覆蓋(override)超類中的這個方法:設計
@Override public double getSalary() { return salary + bonus;//won't work }
然而,這個方法並不能運行。這是由於 Manager 類的 getSalary 方法不能直接地訪問超類的私有域。也就是說,儘管每一個 Manager 對象都擁有一個名爲 salary 的域,但在 Manager 類的 getSalary 方法中並不可以直接地訪問 salary 域。只有 Employee 類的方法纔可以訪問私有部分。若是 Manager 類的方法必定要訪問私有域,就必須藉助共有的接口,Employee 類中的共有方法正式這樣一個接口。code
@Override public double getSalary() { return super.getSalary() + bonus; }
super 關鍵字有兩個用途:一是調用超類的方法,二是調用超類的構造器。 super 不是一個對象的引用,不能將 super 賦給另外一個對象變量,它只是一個指示編譯器調用超類方法的特有關鍵字。
因爲 Manager 類的構造器不能訪問 Employee 類的私有域,因此必須利用 Employee 類的構造器對這部分私有域進行初始化,咱們能夠經過 super 實現對超類構造器的調用。使用 super 調用構造器的語句必須是子類構造器的第一條語句。對象
public class Animal { public Animal() { System.out.println("--Animals--"); } public static int printInit(String s) { System.out.println(s); return 30; } } public class Bird extends Animal { private static int B = Animal.printInit("static Bird region init"); public Bird(){ System.out.println("--Bird--"); } } public class Parrot extends Bird { public Parrot(){ super(); System.out.println("--Parrot--"); } public static void main(String[] arg) { Parrot parrot = new Parrot(); } }
運行結果:繼承
--Animals-- --Bird-- --Parrot--
純繼承關係是純粹的「is-a」(是一種)關係,由於一個類的接口已經肯定了它應該是什麼。繼承能夠確保全部的導出類具備基類的接口,且絕對不會少。基類能夠接收發送給導出類的任何消息,由於兩者有着徹底相同的接口。接口
* Java 語言的繼承是單繼承,不容許一個類繼承多個父類。 * java支持多層繼承(繼承體系)。 * 子類和父類是一種相對概念。 * 備註:頂層父類是Object類,全部的類默認都繼承Object類。
1. 子類只能獲取父類非私有成員 2. 子父類的成員變量的名字不同時,直接獲取父類的成員變量 3. 子父類中成員變量名字是同樣的 * 就近原則,誰離我近我就用誰 * 若是有局部變量就使用局部變量 * 若是沒有局部變量,有子類的成員變量就使用子類的成員變量 * 若是沒有局部變量和子類的成員變量,有父類的成員變量就使用父類的成員變量 * 備註:父類中的成員變量是非私有的,子類才能夠直接訪問。若父類中的成員變量私有了,子類不能直接訪問的。 一般編碼時,咱們通常遵循封裝的原則,能夠在父類中提供公共的setXxx()和getXxx()方法。
例如:get
public class ExtendsDemo2 { public static void main(String[] args) { Kid k = new Kid(); k.show(); } } class Dad{ String name="大蔥"; } class Kid extends Dad{ String name="二蔥"; public void show() { String name = "三蔥"; System.out.println(super.name); System.out.println(this.name); System.out.println(name); } }
1. 子父類的成員方法的名字不同時,直接獲取父類的成員方法 2. 子父類中成員方法名字是同樣的 * 成員方法重名---重寫(Override) * 方法重寫:子類出現於父類如出一轍的方法時(返回值類型,方法名和參數列表都相同),會出現覆蓋效應 也稱爲重寫或者複寫。聲明不變,從新實現。 *重寫的應用 子類能夠根據須要,定義特定於本身的行爲,即沿襲了父類的功能名稱,又能根據子類的須要從新實現父類 的方法,從而進行擴展加強。 * 方法額重載:在一個類中,有多個重名的方法,可是其參數不同 (參數的個數,參數的類型,參數的順序),和返回值無關
備註: 1.子類方法重寫覆蓋父類方法時,必須保證權限大於等於父類的權限。 2.子類方法重寫父類方法時,返回值類型,方法名和參數列表必須如出一轍。 在沒有使用@Override時,子類定義父類方法時,方法名和參數列表可變,返回值類型不可變。
在面嚮對象語言中,繼承是必不可少的、很是優秀的語言機制,它有以下優勢: