淺析Java中的繼承與組合
前言
Java是一個(gè)面向?qū)ο蟮恼Z(yǔ)言。每一個(gè)學(xué)習(xí)過(guò)Java的人都知道,封裝、繼承、多態(tài)是面向?qū)ο蟮娜齻€(gè)特征。每個(gè)人在剛剛學(xué)習(xí)繼承的時(shí)候都會(huì)或多或少的有這樣一個(gè)印象:繼承可以幫助我實(shí)現(xiàn)類(lèi)的復(fù)用。所以,很多開(kāi)發(fā)人員在需要復(fù)用一些代碼的時(shí)候會(huì)很自然的使用類(lèi)的繼承的方式,因?yàn)闀?shū)上就是這么寫(xiě)的(老師就是這么教的)。但是,其實(shí)這樣做是不對(duì)的。長(zhǎng)期大量的使用繼承會(huì)給代碼帶來(lái)很高的維護(hù)成本。
其實(shí)我第一次學(xué)習(xí)java 的時(shí)候根本沒(méi)有聽(tīng)說(shuō)過(guò)組合這個(gè)名詞,老師也更沒(méi)有講解過(guò),我一直以為是我自己落掉了什么知識(shí)點(diǎn),其實(shí)不是的,組合這個(gè)名詞暫且把它定義為一個(gè)思維性的東西吧,相信讀者都接觸過(guò)了,但是并不知道它還有這個(gè)名字。
其實(shí)所謂的組合就是創(chuàng)建一個(gè)新類(lèi)去調(diào)用已經(jīng)創(chuàng)建并且調(diào)試好的類(lèi),那么這個(gè)新類(lèi)就可以把它叫做是一個(gè)組合
例如我創(chuàng)建一個(gè)People
public class People { private String name; private int age; public void setName(String name){ this.name = name; } public String getName(){ return this.name; } public int getAge(){ return this.age; } public void setAge(int age){ this.age = age; } }
那我現(xiàn)在要用這個(gè)類(lèi),我可以給這個(gè)類(lèi)添加一些新的特性,這時(shí)候我們就可以創(chuàng)建一個(gè)新的類(lèi),然后在這個(gè)類(lèi)里創(chuàng)建People的對(duì)象。
比如我現(xiàn)在創(chuàng)建一個(gè)類(lèi)叫做Student
class Student { People people = new People(); }
然后可以在這個(gè)類(lèi)里添加一些屬性,比如定義個(gè)身份為student,在這里我就不在論述了。
接下來(lái)看看繼承,其實(shí)繼承和組合本就有異曲同工之妙,先來(lái)看看是怎樣繼承的。
在java里有一個(gè)叫做extends的關(guān)鍵字,它可以幫助我們繼承,被繼承的類(lèi)我們稱(chēng)作父類(lèi),也可以叫做基類(lèi),超類(lèi)都行,而繼承者我們稱(chēng)作子類(lèi)或者派生類(lèi)等等
這里我們定義一個(gè)類(lèi)
public class Student extends People{ //doSomething }
這樣一來(lái)的話(huà),該類(lèi)就繼承了父類(lèi)的全部成員方法和成員變量,但是注意,聲明為private權(quán)限的字段或者方法是不會(huì)被繼承下來(lái)的。
為了證明這一點(diǎn)我們?cè)趕tudent類(lèi)寫(xiě)一個(gè)方法
public String re(){ return this.name; }
這里編譯器會(huì)報(bào)一個(gè)錯(cuò)"People.name is not visible",從這里就可以看出,被聲明為private 的字段或者方法是不能被繼承下來(lái)的,如果你想把它繼承下來(lái),可以把private改成protected,這樣的話(huà),我們就能順利的繼承下name字段。
這樣我們把People里的字段全部初始化一下,只需在代碼里加上這一段代碼塊就行了
{ this.age = 10; this.name = "zhangsan"; }
接下來(lái)在主函數(shù)里聲明出這個(gè)student
Student student = new Student(); System.out.println(student.getAge());
現(xiàn)在我們驚訝的發(fā)現(xiàn)這個(gè)寫(xiě)法是可行的,盡管我們沒(méi)有在子類(lèi)中聲明任何的字段和方法,我們依然可以調(diào)用getAge();并且可以順利的打印出10
這是因?yàn)槲覀儧](méi)有在子類(lèi)中重載任何方法,所以此時(shí)調(diào)用的是父類(lèi)的getAge,也就可以輕松的訪(fǎng)問(wèn)到父類(lèi)的private聲明的字段了。
看完了這些相信大家對(duì)繼承已經(jīng)有了一個(gè)初步的認(rèn)識(shí),那么在繼承機(jī)制中,各個(gè)類(lèi)的構(gòu)造方法又是怎么被調(diào)用的呢,答案是自父類(lèi)到子類(lèi)依次調(diào)用.
演示的同時(shí)我先聲明三個(gè)類(lèi)Temp1、Temp2、Temp3,與此同時(shí)Temp3繼承自Temp2,而Temp2又繼承自Temp1,這樣的話(huà),我們?cè)诟鱾€(gè)類(lèi)的構(gòu)造方法里都放上一句打印的語(yǔ)句
//Temp1 System.out.println("i'm temp1"); //Temp2 System.out.println("i'm temp2"); //Temp3 System.out.println("i'm temp3");
為了方便我這里就這樣寫(xiě)了,但是大家千萬(wàn)要注意這些是放在各個(gè)類(lèi)的構(gòu)造方法里的。
我們?cè)谥骱瘮?shù)里創(chuàng)建一個(gè)Temp3的對(duì)象
public class Mian{ public static void main(String[] args){ Temp3 temp3 = new Temp3(); } }
我們看控制臺(tái),打印出了
i'm temp1 i'm temp2 i'm temp3
由此可以看出先要?jiǎng)?chuàng)建temp3的對(duì)象,發(fā)現(xiàn)了extends關(guān)鍵字,然后順著繼承鏈往上走,找到temp2,又發(fā)現(xiàn)extends關(guān)鍵字,接著找到temp1,然后調(diào)用temp1的構(gòu)造方法,接著往下挨個(gè)調(diào)用。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
相關(guān)文章
深入分析JAVA Synchronized關(guān)鍵字
這篇文章主要介紹了析JAVA Synchronized關(guān)鍵字的相關(guān)知識(shí),文中代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06Mybatis-plus多數(shù)據(jù)源配置的兩種方式總結(jié)
這篇文章主要為大家詳細(xì)介紹了Mybatis-plus中多數(shù)據(jù)源配置的兩種方式,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起了解一下2022-10-10Mybatis自定義類(lèi)型轉(zhuǎn)換器的使用技巧
這篇文章主要介紹了Mybatis自定義類(lèi)型轉(zhuǎn)換器的使用技巧,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java web入門(mén)指南之在Idea上創(chuàng)建Java web項(xiàng)目
好多書(shū)上的JavaWeb教程都是Eclipse以及MyEclipse,當(dāng)然這里不論IDE的好壞,下面這篇文章主要給大家介紹了關(guān)于Java web入門(mén)指南之在Idea上創(chuàng)建Java web項(xiàng)目的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06