<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # JAVA之旅(六)——單例設計模式,繼承extends,聚集關系,子父類變量關系,super,覆蓋 * * * > java也越來越深入了,大家加油吧!咱們一步步來 ## 一.單例設計模式 * 什么是設計模式? > JAVA當中有23種設計模式,解決某一問題最有效的方法 * 單例設計模式 > 解決一個類在內存中只存在一個對象 > 想要保證對象唯一該怎么做》 * 1.為了避免其他程序過多建立該類對象,先禁止其他程序建立該類對象 * 2.還為了讓其他程序訪問到該類對象,只好在本類中自定義一個對象 * 3.為了方便其他程序對自定義對象的訪問,可以對外提供一些訪問方式 > 這三步怎么怎么實現呢? * 1.將構造函數私有化 * 2.在類中創建一個本類對象 * 3.提供一個方法可以獲取到該對象 > 然后我們的代碼就出來了 ~~~ /** * 單例模式 * * @author LGL * */ public class Single { // 將構造函數私有化 private Single() { } // 在類中創建一個本類對象 private static Single s = new Single(); // 提供一個方法可以獲取到該對象 public static Single getInstance() { return s; } } ~~~ > 當然,我們還有一種寫法——懶漢式 ~~~ /** * 單例模式 * 懶漢式 * @author LGL * */ public class Single { private static Single s = null; public Single() { // TODO Auto-generated constructor stub } public static Single getInstance() { if (s == null) s = new Single(); return s; } } ~~~ > 也有這么一種寫法 ~~~ /** * 單例模式 * 餓漢式 * * @author LGL * */ public class Single { private static Single s = new Single(); public Single() { // TODO Auto-generated constructor stub } public static Single getInstance() { return s; } } ~~~ > 單例模式的寫法多種多樣,只要掌握這個思想就可以了 > > 餓漢式的特點:single類一進內存就已經創建好了對象? > 懶漢式的特點:對象是方法被調用時才初始化,也叫作對象的延遲加載 > > Single類進內存還沒有存在,只有調用了getInstance()方法時才建立對象,這就叫做延遲加載 > > 我們一般用餓漢式,因為他安全,簡單 ## 二.繼承 > 面向對象的思想中的一個思想,繼承,我們可以這樣去理解,我們可以定義一個學生類,他有名字和年齡,還有一個學習的方法 ~~~ /** * 學生 * @author LGL * */ class Student { String name; int age; void study() { System.out.println("學習"); } } ~~~ > 然后我們可以再定義一個工人類 ~~~ /** * 工人 * @author LGL * */ class Worker { String name; int age; void work() { System.out.println("工作"); } } ~~~ > 他同樣有名字和年齡還有一個工作的方法 > > 這個時候我們可以發現,他們都存在相同的關系,他們都是人,人都具備年齡和姓名,所以我們可以將學生和工人的共性提取出來描述,只要讓學生和工人與單獨描述的類有關系就行,也就是繼承 ~~~ /** * 人 * * @author LGL * */ class Person { String name; int age; } ~~~ > 這個Person就叫做父類,超類,基類 > > 然后我們的工人和學生就可以這樣去寫 ~~~ /** * 學生 * * @author LGL * */ class Student extends Person { void study() { System.out.println("學習"); } } /** * 工人 * * @author LGL * */ class Worker extends Person { void work() { System.out.println("工作"); } } ~~~ > 他們是Person的子類,繼承是源于生活,所以工人不能繼承學生,沒有倫理性,千萬不要為了獲取其他類的功能,簡化代碼而繼承,必須是類與類之間有所屬關系才可以繼承,is a 的關系? > 繼承的優點 * 1.提高代碼的復用性 * 2.讓類與類之間產生關系,有了這層關系才有了多態的特性 > JAVA語言中,java只支持單繼承,不支持多繼承 * 為什么不能多繼承?? > 因為多繼承容易帶來安全隱患,當多個父類中定義了相同的功能,當功能內容不同時,子類對象不確定運行哪一個,但是JAVA保留了這種機制,并用另一種體現形式來表示,多實現。 JAVA支持多層繼承,也就是一個繼承體系 如何使用一個繼承體系的功能? * 想要使用體系,先查閱體系中父類的描述,因為父類中定義的是該體系中的共性內容,通過了解共性功能就可以知道該體系的基本功能,那么,這么體系已經可以基本使用了。 * 那么集體調用時,要創建最子類的對象,為什么?一是因為有可能父類不能創建對象,二是創建子類對象可能使用更多的功能,包括基本的也包括特有的 > 簡單的說一句:查閱父類功能,創建子類對象使用功能 ## 三.聚集關系 > 這個概念可能很多人不是很熟悉,確實我們實際開發當中很少提到,我們對象和對象之間,不光有繼承關系,還有組合關系, * 聚合 > 球員是球隊中的一個,球隊中有球員,這就是聚合關系 * 組合 > 手是人身體的一部分,腿是身體的一部分,這就是組合關系,你說這和聚合沒什么不同,那你就錯了,要知道,球隊少了個球員沒事,人少胳膊少腿就有事哦,所以組合關系更加緊密一點 > 都是吧對象撮合在一起,像我們繼承是秉承一個is a的關系,而聚集是has a的關系,誰里面有誰 > > 這個關系我們就不多做贅述了 > > 我們關系講完了,現在應該可以用代碼去表示表示了,這里我就用當繼承關系時,子類和父類之間的變量關系來舉例 ## 四.子父類變量關系 > 我們來探索一下子父類出現后,類成員的特點 * 1. 變量 * 2.函數 * 3.構造函數 > 我們一步步來分析 ### 1.變量 > 我們擼一串代碼 ~~~ //公共的 類 類名 public class HelloJJAVA { // 公共的 靜態 無返回值 main方法 數組 public static void main(String[] str) { /** * 子父類出現后,類成員的特點 */ Zi z = new Zi(); System.out.println("num1 = " + z.num1 + "\n" + "num2 = " + z.num2); } } /** * 父類 * * @author LGL * */ class Fu { int num1 = 4; } /** * 子類 * * @author LGL * */ class Zi extends Fu { int num2 = 5; } ~~~ > 這樣,是不是很容易知道輸出的結果 ![這里寫圖片描述](http://img.blog.csdn.net/20160523211826081) > 但是我們那會這么簡單,我們還有特殊情況 ~~~ //公共的 類 類名 public class HelloJJAVA { // 公共的 靜態 無返回值 main方法 數組 public static void main(String[] str) { /** * 子父類出現后,類成員的特點 */ Zi z = new Zi(); System.out.println("num1 = " + z.num + "\n" + "num2 = " + z.num); } } /** * 父類 * * @author LGL * */ class Fu { int num = 4; } /** * 子類 * * @author LGL * */ class Zi extends Fu { int num = 5; } ~~~ > 當子類和父類都有相同的變量的時候,現在該打印什么呢? ![這里寫圖片描述](http://img.blog.csdn.net/20160523212055161) > 沒錯,打印了子類的值,為什么?因為輸出的num前面其實默認帶了一個this,如果我們要打印父類的值,需要加super,這是一個新的關鍵字了 ~~~ void show(){ System.out.println(super.num); } ~~~ > 結果顯而易見了 ![這里寫圖片描述](http://img.blog.csdn.net/20160523212344978) > 所以變量的特點:如果子類中出現非私有的同名成員變量時,子類要訪問本類中的成員變量,用this,子類訪問父類中的同名變量,用super,this和super的使用幾乎一致,this代表的是本類對象的引用,super代表父類對象的引用 > > 不過我們也不會這么蛋疼在父類創建又在子類創建,我們來看第二個 ### 2.函數 > 也就是方法,我們正常的應該是這樣寫的 ~~~ //公共的 類 類名 public class HelloJJAVA { // 公共的 靜態 無返回值 main方法 數組 public static void main(String[] str) { /** * 子父類出現后,類成員的特點 */ Zi z = new Zi(); z.show1(); z.show2(); } } /** * 父類 * * @author LGL * */ class Fu { void show1() { System.out.println("fu"); } } /** * 子類 * * @author LGL * */ class Zi extends Fu { void show2() { System.out.println("zi"); } } ~~~ > 這是很正常的實現 ![這里寫圖片描述](http://img.blog.csdn.net/20160523214703453) > 我們當然要說一種特殊情況,子父類方法同名我們該怎么辦?我們運行一下 ![這里寫圖片描述](http://img.blog.csdn.net/20160523214831735) > 這是子運行了,這種情況叫做覆蓋(重寫),這個特性的特點 * 當子類出現和父類一模一樣的函數時,當子類對象被調用了該函數,會運行子類函數的內容,如同父類的函數被覆蓋一樣,這種情況就是覆蓋了 > 當子類繼承了父類,沿襲了父類的功能到子類中,到子類中,但是子類雖具備該功能,但是功能的內容卻和父類不一致,這時沒有必要定義新功能,而是使用覆蓋特性,保留父類的功能定義并重寫功能內容 * 覆蓋 > 1.子類覆蓋父類,必須保證子類權限大于等于父類權限才可以覆蓋,否則編譯失敗? > 2.靜態只能覆蓋靜態(一般沒人用) * 記住 > 重載:只看同名函數的參數列表? > 重寫:字符類方法要一模一樣 ,包括返回值類型 ### 3.構造函數 > 最后一個特點了 ~~~ //公共的 類 類名 public class HelloJJAVA { // 公共的 靜態 無返回值 main方法 數組 public static void main(String[] str) { /** * 子父類出現后,類成員的特點 */ Zi z = new Zi(); } } /** * 父類 * * @author LGL * */ class Fu { public Fu() { System.out.println("fu"); } } /** * 子類 * * @author LGL * */ class Zi extends Fu { public Zi() { System.out.println("zi"); } } ~~~ > 我們現在運行一下 ![這里寫圖片描述](http://img.blog.csdn.net/20160523220715613) > 你會疑問,我明明實例化的是子類,怎么父類也實例化了,因為子類構造函數的第一行默認有一個方法 ~~~ super(); ~~~ > 在對子類對象進行初始化時,父類的構造函數也會執行,那就是因為子類的構造函數默認第一行有一條隱式的語句super();他會訪問父類中空參數的構造函數,而且子類中所有的構造函數默認第一行都是super() * 為什么子類一定要訪問父類中的構造函數? > 因為父類中的數據子類可以直接獲取,所有子類建立對象的時候,需要先查看父類如何對這些數據進行初始化的,所有子類對這些對象初始化時,要先訪問父類中的構造函數,如果要訪問父類中指定的構造函數,可以手動定義super(xx,xx)的方式。 * 注意 > super語句一定定義在子類構造函數的第一行 * 結論: > 子類的所有的構造函數,默認都會訪問父類中空參數的構造函數,因為子類每一個構造函數內的第一行都有一句隱式的super,當父類中沒有空參數的構造函數時,子類必須手動通過super或者this語句的形式指定要訪問父類中的構造函數 > 當然,子類的構造函數也可以指定this來訪問本類中的構造函數,子類中至少會有一個構造函數會訪問父類中的構造函數,這個結論就是子類的實例化過程,逐級向上查找 > > 父類也向上查找,他找的是JAVA中所有類的老爹——Object > > 行,我們本篇幅就閑到這里吧,概念多了,反而難以消化,我們要一點點的來 ## 如果有興趣可以加群:555974449,這可能是迄今為止最和諧的IT群了 版權聲明:本文為博主原創文章,博客地址:http://blog.csdn.net/qq_26787115,未經博主允許不得轉載。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看