Java編程里類的繼承


 

    今天,我們將要討論的內容是Java里面類的繼承的相關概念。

    說到繼承,我相信大家都不陌生。生活中,子承父業,子女繼承父母的財產,這就是繼承。實際上,Java里的繼承也是如此。對於一個類來說,它的數據成員和方法就是它的財產,而申明另一個類接收了這個類的財產,這就是Java里的繼承。

    接下來我將就幾個方面,談一談繼承的相關知識。

一、繼承的基本格式與意義

    在上文,我們了解了什么叫做繼承。那么,如何使用繼承?

    繼承的關鍵詞是extends。繼承的一般格式為:public class 類名 extends 類名{};

    假定有兩個類,A、B,在申明B類的時候,我們要求B類繼承A類的數據成員與方法。

    具體實現如下:

    繼承有兩大意義。一是提高了代碼的重用性,二是提高了程序的擴展性。繼承能使得我們的代碼更加簡易,同時也更加靈活。

二、什么時候使用繼承

    上文我們講到,繼承能提高代碼的重用性,提高程序的擴展性。那么,我們不禁要問,什么時候,我們可以使用到繼承?

    我的理解是,當兩個類存在包含關系的時候,我們為了簡化程序,可以使用到繼承。

    舉個例子,車是一個類,公交車也是一個類。兩個類存在包含關系。那么,在申明公交車這個類的時候,對於一些車共有的數據成員和方法,我們可以讓它繼承車這個類從而獲取這些屬性和方法。而對於一些公交車特有的屬性和方法,我們可以在公交車類當中進行添加。比如說,定義一個車類,它有三個屬性值,長度、寬度、重量。而定義一個公交類,我們需要添加上一個takepeople的方法。

    具體實現如下:

三、繼承的內容

    大家可能會注意到一個細節,那就是上文當中我編寫的代碼,無論是數據成員還是方法,我給它的訪問修飾符都是public。我們知道,在Java里面,訪問修飾符總共有四種,那么,子類是否能夠繼承下來父類所有的屬性和方法呢?事實上,子類是可以接收父類所有的屬性和方法的,也就是說,無論訪問修飾符是public還是private,子類都能夠從父類那里接收到。但是,對於私有域,子類是不能夠去訪問的。而Java中關於繼承的定義是獲取可以訪問的屬性和方法,所以,我們說私有量是不被繼承的。

四、方法重寫

    什么叫方法重寫?方法的重寫就是在一個子類中,重寫它繼承的父類的方法的過程。重寫的前提是,首先要有至少兩個存在繼承關系的類。其次,子類在重寫方法的過程中,方法的訪問修飾符必須大於或者等於父類中方法的訪問修飾符。重寫不能改變方法的方法名、返回值類型、參數,它只能更改方法體內的內容。注意一點,方法重寫后不能與原方法相同,否則不能稱為重寫。

    比如,申明一個學生類,一個大學生類,讓大學生類繼承學生類,重寫學習方法,具體代碼如下:

    這就是方法重寫的具體舉例。

五、super關鍵字

    接下來,我們來認識一下super關鍵字。

    談到super,我們可以聯系到之前討論過的this關鍵字。關於this,我們可以用this.方法(數據成員)這樣的方法去調用當前類的屬性和方法,也可以用this(參數類型 參數名)這樣的方式去調用當前類的構造方法。this是指向當前類的一個類似指針的引用,super與this類似,它指向的是當前類的父類。我們注意到,當你的父類存在參數不為空的構造方法的時候,往往你的子類就會出現報錯的情況。這個時候,我們就需要用到super去調用父類的構造方法。繼續以上文所舉的學生與大學生為例,我們在學生類當中添加一個帶參的構造方法。具體代碼如下:

六、自動轉型與強制轉型

    有了繼承與方法重寫,接下來,我們來認識一下自動轉型和強制轉型。

    在這之前,我們先來回想一下類的實例化的過程。實例化類的格式是:類名 對象名=new 構造方法名(參數類型 參數...)。

    自動轉型的格式有兩種,第一種:父類名 對象名=new 子類構造方法(參數類型 參數名...)。

                                   第二種:public void method(父類名  參數名){

              }

              子類名 對象名a = new 子類構造方法(參數值,...);

                                       父類名  對象名b = new 子類構造方法(參數值,...);

              method(對象名a);

              method(對象名b);

    我們知道,經過自動轉型后,我們將不能調用子類添加的方法和數據成員,那么,我們不禁要問,轉型后的對象所調用的方法,究竟是掉的父類的方法還是子類經過重寫后的方法呢?我們不妨來做一次測試,代碼如下:

    讓我們再來看一看運行結果:

    沒錯,結果顯示,我們調用的是子類重寫后的study方法,為什么呢? 

    我們之前論述過,實例化類的過程。類名 對象名,在棧中開辟一塊內存,然后記錄下對象名。new 構造方法名(參數類型 參數名...),這是在堆中開辟出一塊內存並存儲下構造方法所在類的數據成員和方法。=,在兩塊內存之間建立連接,並且在棧中對象名所在位置添加上數據所在堆的位置。而在自動轉型的過程中,因為我們調用的是子類的構造方法,所以,我們獲取的是子類的study方法。事實上,子類中新增的屬性和方法,同樣存在在內存當中,而因為對象是父類對象,所以新增的屬性和方法則被隱藏起來無法調用。

    認識了自動轉型,接下來我們來認識一下強制轉型。在翻閱別人的博客過程中,我看到一種舉例,非常喜歡,所以,我也將用這個例子向大家解釋下強制轉型。在我看來,繼承一般是存在與具有包含關系的兩個及以上的類之間。比如說,動物與狗。狗是動物的子類。什么是自動轉型,自動轉型就是申明一個動物引用指向狗。簡而言之,就是將狗轉型成動物。很明顯,狗是動物,所以,在轉型過程中,不會存在什么問題。但是,強制轉型的話,就容易出現一些問題。動物轉型成狗,換句話說,是動物就是狗。這很明顯是不正確。所以,除非你判定這個動物是狗,你才能使用強制轉型,否則,計算機將會報錯。舉個例子,首先你定義一個狗,然后你通過自動轉型將它轉型成動物,之后你再通過強制轉型將它變回狗,這樣的強制轉型是允許的。在自動轉型中,子類添加的屬性和方法被隱藏,在強制轉型后,被隱藏的內容得以恢復。除了這種情況,我們還可以采用判斷這個動物是不是狗之后再確定是否進行強制轉型的方法。這里介紹一個新的關鍵字,instanceof。我們可以通過它去判斷這個動物究竟是不是狗。用法如:animal instanceof dog。

七、接口

    最后,我要講到的是接口的部分相關知識。我們知道,Java不同於C++,Java中只允許繼承一個父類。顯然,在有的時候,只能繼承一個父類是不能夠滿足我們的需求的。所以,Java引入了另一個概念,接口。繼承一個類,我們稱為繼承。對於接口,我們用實現,實現一個接口。我們知道,類里面有抽象類的說法,在我的理解中,接口是比抽象類更抽象的東西。定義一個接口的格式:

    對於接口里面的屬性,它必須是一個靜態數據,而在接口里定義的方法,一定是一個抽象方法。這就是關於接口的定義。

    實現接口的關鍵字是implements。需要注意的是,當你實現接口后,而你的類又不是一個抽象類的話,那么,你需要重寫接口內所有的抽象方法。很好理解,因為你繼承了抽象方法,而你又不是一個抽象類,自然就會報錯了。

  

    關於類的繼承方面的知識,我暫時就討論這么多,期待大家的指正,歡迎大家一起來探討。

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM