java中當咱們要使用別人的代碼的時候,能夠經過建立新類來複用代碼,而沒必要從頭開始編寫,能夠直接使用別人已經開發並調試好的類。java
咱們將使用兩種方法達到使用類而不破壞現有程序代碼的目的。app
第一種:組合 第二種:繼承spa
組合:只須要在新類中產生現有類的對象。因爲新類是由現有類的對象所組成的,因此稱之爲組合設計
繼承:按照現有類的類型來建立新類。無需改變現有類的形式。採用現有類的形式並在其中添加新代碼。調試
並且編譯器能夠完成其中大部分工做。繼承是面向對象程序設計的基石之一。就兩種方法而言其語法和行爲大可能是相似的,都是利用現有類型生成新類型。咱們將瞭解到這兩種代碼的重用機制。code
首先介紹一下toString(), 由於咱們要常常用到toString().當你須要一個String卻傳入一個對象的時候,編譯器就會默認調用該對象的toString方法.對象
package reusing; // Composition for code reuse. class WaterSource { private String s; WaterSource() { System.out.println("WaterSource()"); s = "Constructed"; } public String toString() { return s; } } public class SprinklerSystem { private String valve1, valve2, valve3, valve4; private WaterSource source = new WaterSource(); private int i; private float f; public String toString() { return "valve1 = " + valve1 + " " + "valve2 = " + valve2 + " " + "valve3 = " + valve3 + " " + "valve4 = " + valve4 + "\n" + "i = " + i + " " + "f = " + f + " " + "source = " + source; } public static void main(String[] args) { SprinklerSystem sprinklers = new SprinklerSystem(); System.out.println(sprinklers); } } /* * Output: WaterSource() valve1 = null valve2 = null valve3 = null valve4 = * null i = 0 f = 0.0 source = Constructed */// :~
這裏是須要一個sprinklers的string 則調用了sprinklers的toString(),須要一個source的string,調用了WaterSource的toString()返回了一個s繼承
而SpinklerSystem中的source 則是使用了組合技術,組合技術沒別的,只需將對象的引用置於新類中便可。接口
繼承是java 必不可少的一部分,當你建立一個類的時候,老是在繼承,除非你明確的聲明繼承自某個類。不然老是隱式的繼承自標準根類Object類。開發
繼承的語法,只須要聲明新類與舊類「類似」。經過關鍵字「extends」 實現的。 這麼作會自動的獲得基類中全部的成員包括域和方法。
一個繼承的例子:
package reusing; //: reusing/Detergent.java // Inheritance syntax & properties. import static net.mindview.util.Print.*; // 清潔劑,洗面奶,去污粉 class Cleanser { private String s = "Cleanser"; public void append(String a) { s += a; } public void dilute() { append(" dilute()"); } public void apply() { append(" apply()"); } public void scrub() { append(" scrub()"); } public String toString() { return s; } public static void main(String[] args) { Cleanser x = new Cleanser(); x.dilute(); x.apply(); x.scrub(); print(x); } } public class Detergent extends Cleanser { // Change a method: public void scrub() { append(" Detergent.scrub()"); super.scrub(); // Call base-class version } // Add methods to the interface: public void foam() { append(" foam()"); } // Test the new class: public static void main(String[] args) { Detergent x = new Detergent();// 洗滌劑的意思 x.dilute(); // 稀釋沖淡 x.apply(); // 塗上 x.scrub();// 擦洗 x.foam();// 起沫 print(x); print("Testing base class:"); Cleanser.main(args); } } /* * Output: Cleanser dilute() apply() Detergent.scrub() scrub() foam() * Testing base class: Cleanser dilute() apply() scrub() */// :~
解釋:這個類有點亂,若是啓動的是Detergent.main(),整個過程是這樣的:在Cleanser的接口有一組方法:append()、dillute()、apply()、scrub()、toString().因爲Detergent是由關鍵字extends從Cleanser導出的。因此子類能夠在其接口中自動的得到這些方法,儘管看不到在子類中的顯式定義。
父類和子類中的方法都是對私有屬性s的操做。由於沒有構造方法,因此s在最開始是"Cleanser" 。而後調用x.dilute(),x.apply(), x.scrub(), x.foam() 在Cleanser後面依次拼接了字符串dilute() apply() Detergent.scrub() scrub() foam() 而後由於子類中沒有toString()方法,當print(x)的時候調用的是繼承自父類的toString()。將s輸出。只是須要注意子類的scrub()中, 會調用基類中的scrub()方法。同理父類中的main()也是同樣的。