java物件導向

來源:互聯網
上載者:User

標籤:.net   super   自動   特徵   包名   編程   獨立性   建議   架構類   

     Java語言完全支援物件導向的繼承、封裝、多態,純粹的物件導向的程式設計語言。Java以對象為中心,整個程式由類(Java的最小的程式單位)組成。Java是一個靜態語言,一個類完成定義後,只要不重新編譯,則類和其對象的方法和屬性是固定的。Java引入了包的機制,提供類的多層命名空間,用於解決類命名衝突,類檔案管理。一旦在源檔案中使用了package packageName,則意味著該源檔案裡的所有類都屬於這個包,完整類名為包名+類名。java的包機制需要源檔案裡的package指定包名還需要class檔案放在對應的路徑下。同一個包的類可以自由訪問,不同的包需加首碼,即使是父子包,例如:xxx.xxx.Test test = new xxx.xxx.Test test();為解決此問題引入了import關鍵字用於匯入指定包層次下的某個類或全部類import package.subpackage...ClassName/*,有時兩個包中有相同的類名,此時則又需要使用全路徑指定哪個包名下的此類。JDK1.5之後也可以使用import static package subpackage...ClassName.filedName/*來匯入類的某個或全部靜態屬性。

       繼承是物件導向實現軟體複用的重要手段,子類作為一種特殊的父類擁有父類的屬性和方法;Java是單繼承的語言(即只能有一個直接父類),因為多重繼承可能引發繼承結構的混亂,程式難以理解。封裝指的是將對象的屬性和細節隱藏起來,不允許外部直接存取,通過公有的方法暴露給外部,讓方法來操作或訪問這些屬性,從而隱藏類的細節、在方法內實現邏輯控制、限制對屬性的不合理訪問、可進行資料檢查,有利於保證對象資訊的完整性,便於修改,提高代碼的可維護性;多態指子類對象可以賦值給父類變數,但運行時依然動態表現出子類的行為特徵。類時對象的抽象,對象是類的一個執行個體,對象具有標識唯一性、分類性、多態性、封裝性、模組獨立性好等基本特點,而類的封裝性則提高了類的內聚,降低了對象之間的耦合。訊息時一個類的執行個體和另一個類的執行個體之間傳遞的資訊,實現了對象間的互動。

       抽象是將軟體系統的功能需求抽象成我們所要使用的資料、行為特徵。

       基於對象和物件導向的區別在於,基於對象僅僅實現了封裝,未實現繼承和多態,例如JS。

       Java語言裡,一切皆是對象(除8個基礎資料型別 (Elementary Data Type)),我們通過引用來訪問它,而且對象具有唯一性,每個對象都有唯一的標識引用它,如果失去了標識,則GC會進行回收。

       類之間的結構關係:1.一般—特殊結構:也被稱為分類結構即繼承,表現為"is a"關係,Java通過extands實現,繼承關係中從多個子類中抽象出其共有父類的過程,類似組合關係裡從整個類裡提取出潛入類的過程即繼承關係中從父類派生子類的過程,類似於組合關係裡把潛入類對象組合成整體類的過程2.整體—部分結構:也被稱為組裝結構即組合,表現在“has a”關係,Java通過在一個類中儲存另一個對象的引用來實現。如果對已有的類做一番改造擷取一個特殊的版本即抽象的類能改造成適用於某種特定需求的類,則用繼承。例如動物和狼。如果類之間有明確的部分和整體的關係,例如人和手,則應用組合,把手作為人的嵌入屬性從而用手的方法實現人的方法。

       類是一種引用資料類型,類裡只能包含屬性、方法、構造器、初始化塊、內部類(包括枚舉和介面)5種成員,類一般按如下方式定義:[ 修飾符 ] class 類名{零到多個構造器定義.. 零到多個屬性... 零到多個方法...}修飾符可以是public、final也可以完全省略,類名首字母大寫。定義屬性的格式文法:[ 修飾符 ] 屬性類型 屬性名稱 [ =預設值 ]修飾符一般是public、private、protected、static、final等。屬性名稱首字母小寫。定義方法的文法:[ 修飾符 ] 方法傳回值類型 方法名(形參列表){零到多條語句組成的方法體},修飾符可以是public、private、protected、static、final、abstract。static修飾的方法只能訪問static的成員,因為他們均屬於類方法,而不用其修飾的屬於執行個體成員和方法(原因參見①)。構造器的文法定義格式如下:[ 修飾符 ] 構造器名 (形參列表){ 零到多條語句組成的方法體 }修飾符可以是public、protected、private其中之一,也可以省略,但不允許修飾符是static,名字必須和類名相同,構造器的傳回值是隱式的。系統提供的構造器是沒有參數的,當我們自己定義了一個構造器時,系統將不會提供預設的構造器。使用new構造一個對象時,堆和棧中儲存的內容和C相同,需要大家仔細研究一下。當對象不被任何引用所使用時,記憶體回收行程將回收他們,和C/C++一樣將這些引用變數置為null,即切斷了參考關聯性,等待GC回收。成員變數和局部變數的首字母命名小寫,其餘單字首大寫。

      Java的參數傳遞機制是值傳遞,即傳遞實際參數的副本,而參數本身不會受到影響。形參可變的方法定義如下public void test(int a, int b, String... persons)他的定義和public void test(int a, int b, String[] persons)效果相同,但調用兩者時,形參可變的方法即可傳入數組也可以傳入多個String值,而後者只能傳遞數組,定義形參可變的方法只能有一個可變的形參,且位於方法形參列表的最後。

      變數包括成員變數(執行個體屬性和static修飾的類屬性)和局部變數(形參,方法局部變數、代碼塊局部變數),類的屬性的範圍同類的生命週期,執行個體屬性的範圍同執行個體。成員變數定義時無需初始化,但局部變數定義則需要初始化(形參除外,因為形參在調用方法時,系統已完成了初始化)。如果方法中的局部變數和成員變數同名,可使用this或類名訪問成員變數。類是在第一次使用的時候初始化,此時類成員變數在堆中分配記憶體並初始化,而成員變數在第一次new執行個體時初始化且儲存地區不同於類成員變數。局部變數只有在初始化後才會分配記憶體空間,且位於棧上。

       存取控制符;private->default->protected->public,詳細補全圖

       建構函式式Java建立對象的重要途徑⑦(即使原廠模式、反射等方式建立對象,實質依然是構造器),Java提供至少一個構造器(構造器支援重載)並經常在構造器中進行自訂的初始化操作。由於構造器主要用於被其他方法調用返回類的執行個體,因此通常將建構函式設定為public,從而允許系統中的其他類建立該類對象,特殊情況才可能設為protected(子類調用),private(不允許其他類建立)。

       繼承(擴充)的文法如下:修飾符 class SubClass extends SuperClass{//類定義部分}Java的子類不能繼承父類的構造器。擴充和派生是對立的同概念,如果沒有顯示的指定,類的直接父類是java.lang.Object,要麼就是間接父類。繼承雖然實現了重用,但會破壞父類的封裝性從而造成耦合,而組合實現了類重用且有更好的封裝。如果出於類服用的目的,組合也可以實現。通常是在原來作為子類的類中定義private 父類對象並在建構函式中初始化傳入此對象賦值給此private對象,同時實現原父類的方法⑩。

       多態,Java的參考型別有兩種,一種是編譯時間的類型,一種是運行時的類型,分別在聲明變數的類型和實際運行時賦給變數的對象的類型決定,如果編譯時間的類型和運行時的類型不一致則為多態。Java允許把一個子類對象賦給一個父類引用變數,無需任何類型轉換,被稱為系統自動完成向上轉型,因為就會出現BaseClass baseclass = new SubClass();baseClass在啟動並執行時候表現出不同的行為,但需注意如果調用了父類中沒有而子類中沒有的方法,雖然運行時確實存在,但是編譯時間無法通過(可以通過強制類型轉換成子類的類型⑨)。但是屬性和方法不同,屬性沒有多態性即訪問編譯時間的屬性,在此過程中實際建立了兩個對象(父類和子類對象)。

       初始化塊是Java除了屬性、方法和構造器外的第四種成員,一個類裡面可以有多個初始化塊。它也可以對java對象進行初始化操作,文法如下:[static]{ //任何可執行代碼}初始化的順序是先執行初始化塊或聲明屬性時指定的初始值,最後是建構函式的初始化。初始化一般用在給所有對象設定同一個初始值,從而提高代碼的可維護性,類初始化塊即static修飾的在對象初始化前執行,他不能對執行個體屬性進行初始化,以上的也和構造器一樣會向讓追溯,類初始化階段,先執行最頂層父類的靜態初始化塊,依次向下,僅執行一次,接著對象初始化,先執行最頂層父類的初始化塊、構造器然後依次向下。JVM第一次使用類時,準備階段為所有的靜態屬性分配記憶體,初始化階段即是執行靜態初始化塊和類屬性時指定的初始值。

       ①static方法只能訪問static成員的本質原因是在static方法中使用this關鍵字,無法找到合適的this對象,所以static不能使用this引用,也就不能使用非static的成員和方法。當類中的一個方法調用另一個方法時預設隱藏了this,當調用靜態方法和屬性時,預設隱藏了類。注意this對象的使用和範圍。static的方法和屬性是類和執行個體共同擁有,因此類和執行個體(即使執行個體定義為null,但如果調用的是執行個體方法和屬性則會報NullPointerException)均可調用,且執行結果相同,普通的方法和屬性只能用執行個體對象調用且執行結果可能會因不同的對象而不同。Java在建立某個類對象時會隱式建立該類的父類對象,使用super即是指向父類對象,this則是指向到調用該方法的對象(子類對象),即super指向的是this指向對象的父物件。因此super也不能出現在static的類方法中(找不到匹配的父物件)

      ②遞迴要向已知方向遞迴

      ③重載:方法命相同,形參列表不同(方法的傳回值不能用來區分重載的原因是因為調用時可能採用f()不需要傳回值的情況,此時系統無法識別),如果形參列表是可變參數,則視情況可能需要傳入A.test(new String[](""))來區分單字串的使用。覆蓋是子類重寫父類的方法,遵循“兩同兩小一大規則”即方法名相同、形參列表相同,兩小指子類方法的傳回值類型比父類方法的傳回值類型更小或相等,子類方法聲明拋出的異常也如此。一大指的子類方法的存取權限應比父類更大或相等。覆蓋要求同是類方法或者執行個體方法,可以使用super調用被覆蓋的執行個體方法,使用父類類名。方法調用父類中被覆蓋的類方法。如果父類方法是private,不可覆蓋,不可訪問。子類可以重載父類的方法。屬性覆蓋:當子類和父類有同名的屬性時,可通過super訪問父類的屬性,而類屬性則可直接用類名訪問。

      ④設計原則:1.使用局部變數的好處是縮小了變數的存留時間,減少開銷。縮短變數的範圍,提高程式的內聚性。2.封裝的目的:一個類往往是一個小模組,我們應該只讓這個模組公開外界需知道的內容,隱藏其他一些內容,進而避免在一個模組內直接操作和訪問另一個模組的資料,模組的設計追求高內聚(儘可能把模組的內部資料、功能實現細節隱藏在模組內部獨立完成,不允許外部直接幹預)低耦合(僅暴露少量的方法給外界使用)。3.類裡面的絕大部分屬性都應該是private,一些static修飾的類似全域變數的屬性才考慮使用public修飾。一些輔助實現該類的工具方法,也應該定義為private.如果父類裡面的方法僅希望被子類重寫,而不想被外面直接調用,則應該用protected修飾這些方法。希望暴露給其他類自由調用的方法應該使用public修飾,例如建構函式,因此父類(頂級類)多數都定義為public,因為大多數情況下希望被其他自由類使用。3.父類的設計原則:盡量隱藏父類內部資料,屬性設為private,不讓子類直接存取;不要讓子類隨意訪問、修改(使用覆蓋即重寫)父類的方法,父類中輔助其他的方法應用private修飾,需要被外部存取的方法用public修飾,但是又不希望被子類重寫的應該使用final修飾。如果父類希望某個方法被子類重寫,但不希望被其他類自由訪問,可以使用protected來修飾該方法,不要在父類構造器中調用被子類重寫的方法(會引發null 指標錯誤)。如果想把某個類設為最終類(即不能作為父類),則可以使用final修飾這個類,JDK中的java.lang.String和System即是如此,或者將父類的構造器用private修飾,這樣子類就無法調用父類的構造器,也就無法繼承。此時可提供一個靜態方法用於建立該類的執行個體。什麼時候使用繼承:子類額外增加屬性,而不僅僅是對父類屬性值的改變,子類需要增加自己專屬的行為方式(包括增加新的方法或重寫父類的方法)。

      ⑤一些描述類或者對象的固有資訊的變數,應定義為成員變數。

      ⑥java常用包:java.lang包含Java語言的核心類String、System、Math、Thread等,Java預設匯入了java.lang,因此使用String,System均不會出錯。java.util包含Java大量的工具類/介面和集合架構類/介面,例如Arrays和List、Set等。Java.NET包含了一些Java網路編程相關的類/介面。java.io包含了輸入/輸出編程相關的類/介面。java.text包含了java格式化相關的類。java.sql包含了java進行JDBC資料庫編程的相關類/介面。Java.awt包含了抽象串口工具集相關的類/介面,主要用於構建圖形化使用者介面。java.swing包含Swing圖形化使用者介面編程相關的類/介面,可用於構建平台無關的GUI程式。

      ⑦構造器是否完全負責建立Java對象:不是,在調用構造器前系統已經為對象分配了記憶體空間並預設初始化,只是此時仍不能被外部調用,只能在構造器中經過this指標引用它,當構造器執行結束,這個對象作為構造器傳回值返回,通常還會付給另一個引用型變數,從而給外部存取此對象。並且通常建議如果自訂了有參數建構函式,額外最好編寫提供一個無參數建構函式。使用this調用另一個重載的構造器只能在構造器中使用,且必須放在構造器執行體的第一句。子類調用父類的構造器使用super來實現,也必須位於第一行,因此this和super不會同時出現。不管用不用super調用父類構造器的初始化代碼,子類都會在自己的構造器初始化之前調用父類構造器。並且會一直追溯到java.lang.Object

     ⑧訪問某個方法中的屬性,訪問順序為:方法中局部變數->尋找當前類中是否有此屬性(變數)->尋找父類,依次上溯到Object。

     ⑨基本類型的資料類型轉換隻能在數值間進行,即:整型、字元型、浮點型,但不能和布爾型之間進行資料類型轉換。參考型別只能把一個父類變數轉換成子類類型且滿足此執行個體編譯時間是父類對象,運行時是子類對象,否則將發生ClassCastException異常,例如double d =3.14; long a = (long)d; Object obj = "hello" String objStr = (String)obj;Object objPri = new Integer(5)String str = (String)objPri異常;為了使代碼更健壯,可以使用if(obj instanceof String){String str = (String)objPri}

     ⑩使用組合關係因為需要new父類並傳入子類的建構函式中從而初始化子類中的父類對象,會不會造成多餘的開銷,因為繼承關係時子類也要預設建立父類,只是此時是程式員顯示的手動建立被嵌入的類對象,所以不會產生多餘的開銷。

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.