【轉】java提高篇(二)-----理解java的三大特性之繼承

來源:互聯網
上載者:User

標籤:更改   細節   title   開發   too   衍生類別   ons   不能   向上轉型   

【轉】java提高篇(二)-----理解java的三大特性之繼承

原文地址:http://www.cnblogs.com/chenssy/p/3354884.html

      在《Think in java》中有這樣一句話:複用代碼是Java眾多令人信服的功能之一。但要想成為極具革命性的語言,僅僅能夠複製代碼並對加以改變是不夠的,它還必須能夠做更多的事情。在這句話中最令人信服的是“複用代碼”,儘可能的複用代碼使我們程式員一直在追求的,現在我來介紹一種複用代碼的方式,也是java三大特性之一---繼承。

繼承

      在講解之前我們先看一個例子,該例子是前篇博文(java提高篇-----理解java的三大特性之封裝)的。

      從這裡我們可以看出,Wife、Husband兩個類除了各自的husband、wife外其餘部分全部相同,作為一個想最大限度實現複用代碼的我們是不能夠忍受這樣的重複代碼,如果再來一個小三、小四、小五……(扯遠了)我們是不是也要這樣寫呢?那麼我們如何來實現這些類的可複用呢?利用繼承!!

      首先我們先離開軟體編程的世界,從常識中我們知道丈夫、妻子、小三、小四…,他們都是人,而且都有一些共性,有名字、年齡、性別、頭等等,而且他們都能夠吃東西、走路、說話等等共同的行為,所以從這裡我們可以發現他們都擁有人的屬性和行為,同時也是從人那裡繼承來的這些屬性和行為的。

      從上面我們就可以基本瞭解了繼承的概念了,繼承是使用已存在的類的定義作為基礎建立新類的技術,新類的定義可以增加新的資料或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。通過使用繼承我們能夠非常方便地複用以前的代碼,能夠大大的提高開發的效率。

      對於Wife、Husband使用繼承後,除了代碼量的減少我們還能夠非常明顯的看到他們的關係。

      繼承所描述的是“is-a”的關係,如果有兩個對象A和B,若可以描述為“A是B”,則可以表示A繼承B,其中B是被繼承者稱之為父類或者超類,A是繼承者稱之為子類或者衍生類別。

      實際上繼承者是被繼承者的特殊化,它除了擁有被繼承者的特性外,還擁有自己專屬得特性。例如貓有抓老鼠、爬樹等其他動物沒有的特性。同時在繼承關係中,繼承者完全可以替換被繼承者,反之則不可以,例如我們可以說貓是動物,但不能說動物是貓就是這個道理,其實對於這個我們將其稱之為“向上轉型”,下面介紹。

      誠然,繼承定義了類如何相互關聯,共用特性。對於若干個相同或者相識的類,我們可以抽象出他們共有的行為或者屬相併將其定義成一個父類或者超類,然後用這些類繼承該父類,他們不僅可以擁有父類的屬性、方法還可以定義自己專屬的屬性或者方法。

      同時在使用繼承時需要記住三句話:

         1、子類擁有父類非private的屬性和方法。

         2、子類可以擁有自己屬性和方法,即子類可以對父類進行擴充。

        3、子類可以用自己的方式實現父類的方法。(以後介紹)。

      綜上所述,使用繼承確實有許多的優點,除了將所有子類的共同屬性放入父類,實現代碼共用,避免重複外,還可以使得修改擴充繼承而來的實現比較簡單。

      誠然,講到繼承一定少不了這三個東西:構造器、protected關鍵字、向上轉型。

構造器

      通過前面我們知道子類可以繼承父類的屬性和方法,除了那些private的外還有一樣是子類繼承不了的---構造器。對於構造器而言,它只能夠被調用,而不能被繼承。 調用父類的構造方法我們使用super()即可。

      對於子類而已,其構造器的正確初始化是非常重要的,而且若且唯若只有一個方法可以保證這點:在構造器中調用父類構造器來完成初始化,而父類構造器具有執行父類初始化所需要的所有知識和能力。

public class Person {    protected String name;    protected int age;    protected String sex;        Person(){        System.out.println("Person Constrctor...");    }}public class Husband extends Person{    private Wife wife;    Husband(){        System.out.println("Husband Constructor...");    }        public static void main(String[] args) {        Husband husband  = new Husband();    }}Output:Person Constrctor...Husband Constructor...

      通過這個樣本可以看出,構建過程是從父類“向外”擴散的,也就是從父類開始向子類一級一級地完成構建。而且我們並沒有顯示的引用父類的構造器,這就是java的聰明之處:編譯器會預設給子類調用父類的構造器。

      但是,這個預設調用父類的構造器是有前提的:父類有預設構造器。如果父類沒有預設構造器,我們就要必須顯示的使用super()來調用父類構造器,否則編譯器會報錯:無法找到符合父類形式的構造器。

public class Person {    protected String name;    protected int age;    protected String sex;        Person(String name){        System.out.println("Person Constrctor-----" + name);    }}public class Husband extends Person{    private Wife wife;    Husband(){        super("chenssy");        System.out.println("Husband Constructor...");    }        public static void main(String[] args) {        Husband husband  = new Husband();    }}Output:Person Constrctor-----chenssyHusband Constructor...

     所以綜上所述:對於繼承而已,子類會預設調用父類的構造器,但是如果沒有預設的父類構造器,子類必須要顯示的指定父類的構造器,而且必須是在子類構造器中做的第一件事(第一行代碼)。

protected關鍵字

      private存取修飾詞,對於封裝而言,是最好的選擇,但這個只是基於理想的世界,有時候我們需要這樣的需求:我們需要將某些事物儘可能地對這個世界隱藏,但是仍然允許子類的成員來訪問它們。這個時候就需要使用到protected。

      對於protected而言,它指明就類使用者而言,他是private,但是對於任何繼承與此類的子類而言或者其他任何位於同一個包的類而言,他卻是可以訪問的。

public class Person {    private String name;    private int age;    private String sex;    protected String getName() {        return name;    }    protected void setName(String name) {        this.name = name;    }    public String toString(){        return "this name is " + name;    }        /** 省略其他setter、getter方法 **/}public class Husband extends Person{    private Wife wife;    public  String toString(){        setName("chenssy");    //調用父類的setName();        return  super.toString();    //調用父類的toString()方法    }    public static void main(String[] args) {        Husband husband = new Husband();                System.out.println(husband.toString());    }}Output:this name is chenssy

      從上面樣本可以看書子類Husband可以明顯地調用父類Person的setName()。

      誠然儘管可以使用protected存取修飾詞來限制父類屬性和方法的存取權限,但是最好的方式還是將屬性保持為private(我們應當一致保留更改底層實現),通過protected方法來控制類的繼承者的存取權限。

向上轉型

      在上面的繼承中我們談到繼承是is-a的相互關係,貓繼承與動物,所以我們可以說貓是動物,或者說貓是動物的一種。這樣將貓看做動物就是向上轉型。如下:

public class Person {    public void display(){        System.out.println("Play Person...");    }        static void display(Person person){        person.display();    }}public class Husband extends Person{    public static void main(String[] args) {        Husband husband = new Husband();        Person.display(husband);      //向上轉型    }}

      在這我們通過Person.display(husband)。這句話可以看出husband是person類型。

       將子類轉換成父類,在繼承關係上面是向上移動的,所以一般稱之為向上轉型。由於向上轉型是從一個叫專用類型向較通用類型轉換,所以它總是安全的,唯一發生變化的可能就是屬性和方法的丟失。這就是為什麼編譯器在“未曾明確表示轉型”活“未曾指定特殊標記”的情況下,仍然允許向上轉型的原因。

謹慎繼承

      上面講了繼承所帶來的諸多好處,那我們是不是就可以大肆地使用繼承呢?送你一句話:慎用繼承。

      首先我們需要明確,繼承存在如下缺陷:

         1、父類變,子類就必須變。

         2、繼承破壞了封裝,對於父類而言,它的實現細節對與子類來說都是透明的。

         3、繼承是一種強耦合關係。     

      所以說當我們使用繼承的時候,我們需要確信使用繼承確實是有效可行的辦法。那麼到底要不要使用繼承呢?《Think in java》中提供瞭解決辦法:問一問自己是否需要從子類向父類進行向上轉型。如果必須向上轉型,則繼承是必要的,但是如果不需要,則應當好好考慮自己是否需要繼承。

      慎用繼承!!!!!!!!!!!!!!!!!!!!!!!!!!!

PS:如果你覺得文章對你有所協助,別忘了推薦或者分享,因為有你的支援,才是我續寫下篇的動力和源泉!
  • chenssy
    出處:http://www.cnblogs.com/chenssy/
    本文著作權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。

【轉】java提高篇(二)-----理解java的三大特性之繼承

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.