05 Java 類和對象

面向?qū)ο笫?Java 最重要的特性。Java 是徹底的、純粹的面向?qū)ο笳Z言,在 Java 中“一切都是對象”。本章將介紹面向?qū)ο蠡A(chǔ)知識。

面向?qū)ο?/p>

  • 相對面向過程而言, 面向?qū)ο蠛兔嫦蜻^程都是一種思想
  • 將功能封裝進對象,強調(diào)具備了功能的對象。
  • 是一種符合人們思考習慣的思想, 可以將復雜的事情簡單化, 將程序員從執(zhí)行者轉(zhuǎn)換成了指揮者.

面向?qū)ο蟮拈_發(fā)過程: 其實就是不斷的創(chuàng)建對象,使用對象,指揮對象做事情。
面向?qū)ο蟮脑O(shè)計過程: 其實就是在管理和維護對象之間的關(guān)系。

面向?qū)ο蟮奶卣鳎?/p>

  • 封裝(encapsulation): 封裝能夠使外部訪問者不能隨意存取對象的內(nèi)部數(shù)據(jù),隱藏了對象的內(nèi)部細節(jié),只保留有限的對外接口。外部訪問者不用關(guān)心對象的內(nèi)部細節(jié),使得操作對象變得簡單。
  • 繼承(inheritance)
  • 多態(tài)(polymorphism): 指在父類中成員變量和成員方法被子類繼承之后,可以具有不同的狀態(tài)或表現(xiàn)行為。

什么是類

Java中用類 Class 來描述事物.是具體事物的抽象,概念上的定義。

  • 屬性:對應類中的成員變量。
  • 行為:對應類中的成員函數(shù)。

類定義包括類聲明和類體兩部分,類定義的語法格式如下:
[public][abstract|final] class className [extends superclassName] [implements interfaceNameList] {類體}

對象的創(chuàng)建

創(chuàng)建對象及訪問對象成員

  1. 聲明對象與聲明普通變量沒有區(qū)別 ,格式為type objectName; 
    聲明對象并不為對象分配內(nèi)存空間,而只是未存儲對象的地址分配內(nèi)存空間
  2. 實例化對象。分為兩個階段:為對象分配內(nèi)存空間和初始化對象,首先使用new運算符為對象分配內(nèi)存空間,然后再調(diào)用構(gòu)造方法初始化對象。格式如下:new 類的構(gòu)造方法();
  3. 通過引用變量訪問對象成員
  • 引用變量名.屬性
  • 引用變量名.方法名(實參表)

什么是方法

方法聲明

修飾符 1 修飾符2... 返回值類型 方法名(形參表) [ throws 異常列表 ] { }
其中返回值是方法在操作完成后返還調(diào)用它的環(huán)境的數(shù)據(jù),形式有2種:

  1. return 表達式; // 方法返回結(jié)果為表達式的值;
  2. return; // 用于無返回值的方法退出,無返回值末尾可不寫;

參數(shù)傳遞

  1. 基本數(shù)據(jù)類型的參數(shù)傳遞是以傳值的方式進行,即將實際參數(shù)的值傳遞給形參; 在方法內(nèi)對形參的修改只影響形參單元,不影響實參
  2. 引用類型(如對象、數(shù)組等)參數(shù)傳遞是按地址進行傳遞的。在方法內(nèi)對形參的訪問實際是訪問所指引用對象

方法的特點:
將功能代碼進行封裝,便于對該功能進行調(diào)用。只有被調(diào)用才被執(zhí)行,提高了代碼的復用性. (注意不能在函數(shù)的內(nèi)部定義方法) 。

方法的重載(Overload):

  • 在同一個類中,允許存在一個以上的同名函數(shù),函數(shù)參數(shù)個數(shù)或類型至少其一不同.
  • 由于只考慮參數(shù)類型和個數(shù)的差異 ,不考慮出現(xiàn)返回值類型的差異. 因為這將導致算法的不確定性,這是不可能存在的。強烈建議重載其返回值類型相同
  • 方法調(diào)用的匹配處理原則是,首先按“精確匹配”原則去查找匹配方法,如果找不到,則按“自動類型轉(zhuǎn)換匹配”原則去查找能匹配的方法。
    • 所謂“精確匹配”就是實參和形參類型完全一致
    • 所謂“自動轉(zhuǎn)換匹配”是指雖然實參和形參類型不同,但能將實參的數(shù)據(jù)按自動轉(zhuǎn)換原則賦值給形參。

mybatis 的 SQL 操作方法簽名不支持重載。

方法的覆蓋(Override)

  • 方法名、參數(shù)列表、完全相同才會產(chǎn)生方法覆蓋;
  • 返回類型通常也要一致,只有返回類型為引用類型時,允許子類方法的返回類型是父類方法返回類型的子類型。
  • 覆蓋不能改變方法的靜態(tài)與非靜態(tài)屬性。子類中不能將父類非靜態(tài)方法定義為靜態(tài)方法,反之也一樣。
  • final 方法不能被覆蓋。

不允許子類方法的訪問修飾符比父類有更多的限制。例如:子類不能將父類的 public 方法定義為 protected 方法。但可以將父類的 private 方法在子類中重新定義為 public 方法.通常將子類方法訪問修飾符與父類保持一致.

構(gòu)造方法

作用: 給對象進行初始化

構(gòu)造方法的特點

  • 構(gòu)造方法的名稱必須與類名同名;
  • 構(gòu)造方法沒有返回類型, 包括void, 所以不可以寫return語句;
  • 構(gòu)造方法只能與 new 運算符結(jié)合使用;
  • 通常一個類可提供多個構(gòu)造方法,這些方法的參數(shù)不同。在創(chuàng)建對象
    時,系統(tǒng)自動調(diào)用參數(shù)匹配的構(gòu)造方法為對象初始化
  • 如果一個類未指定構(gòu)造方法,則系統(tǒng)自動提供的無參構(gòu)造方法,但如果自定義了構(gòu)造方法,則系統(tǒng)不再提供無參構(gòu)造方法。
    無參構(gòu)造方法形式如下: public Person() { } , 所以自己最好還要默默的加入無參構(gòu)造方法
  • 什么時候定義構(gòu)造方法: 當分析事物時, 該事物具備一定特性或行為, 可以將這些內(nèi)容定義在構(gòu)造方法中.

一個類默認有一個空參數(shù)的構(gòu)造函數(shù),這個構(gòu)造函數(shù)的權(quán)限與所屬類一致. 如果類被 public 修飾,則默認的構(gòu)造函數(shù)也被 public 修飾.總之默認構(gòu)造函數(shù)的權(quán)限是隨著類而變化.

對象的初始化和構(gòu)造方法

在創(chuàng)建對象時,要給對象的屬性成員分配內(nèi)存空間,同時進行初始化。

  1. 如果定義屬性成員時沒有指定初值,則系統(tǒng)自動指定初值.在定義屬性成員時也可以指定初值.public class Point { private int x=10; ……
  2. 指定初值的另一種辦法是通過初始化塊來設(shè)置對象的初值(也叫做構(gòu)造代碼塊,它是給所有對象進行統(tǒng)一初始化)。
    // 注意首先是按照屬性定義的初值,然后是初始化塊,
  3. 最后是構(gòu)造方法:構(gòu)造方法是給對相關(guān)設(shè)置初值的規(guī)范方法,構(gòu)造方法是根據(jù)方法參數(shù)給對象屬性賦不同的值

成員變量

聲明類體中成員變量語法格式如下:
[public | protected | private ] [static] [final] type variableName; //成員變量

成員方法

[public | protected | private ] [static] [final | abstract] [native] [synchronized] type methodName([paramList]) [throws exceptionList] { //方法體 }

static關(guān)鍵字

靜態(tài)屬性

用 static 修飾的屬性是屬于類的靜態(tài)屬性, 相應的成員變量為類變量

  1. 類變量的訪問形式
  • 在本類中直接訪問:count
  • 通過類名訪問:User.count
  • 不建議通過類的一個對象訪問,如:x1.count, 實際上還是通過類名的方式訪問
  1. 給類變量賦初值
    默認賦值即可,也可以用靜態(tài)初始化代碼塊 static{count=100;}
    // 靜態(tài)初始化代碼的執(zhí)行是在main方法執(zhí)行前完成。
  2. 被 static 修飾的類成員特點:是共享數(shù)據(jù), 隨著類的加載而加載, 優(yōu)先于對象存在, 被所有對象所共享, 可以直接被類名調(diào)用.

靜態(tài)方法

用 static 修飾的方法稱為靜態(tài)方法,也叫類方法. 在 static 方法中只能處理類變量,也可訪問其它 static 方法,但不能訪問任何歸屬對象空間的變量或方法.
而非靜態(tài)成員變量和方法卻可以訪問靜態(tài)資源.

  • 靜態(tài)方法中不可以寫 this,super 關(guān)鍵字
  • 主函數(shù)是靜態(tài)方法.

tip: 創(chuàng)建某個工具類, 可只提供相應的靜態(tài)方法, 進一步為了讓某個類不能創(chuàng)建對象, 可以私有化構(gòu)造函數(shù).

理解 this 和 super

出現(xiàn)在類的實例方法或構(gòu)造方法中,this 代表所在函數(shù)所屬對象的引用。用 this 作前綴可訪問當前對象的實例變量或成員方法.

  1. this.實例變量; // 能加 this 則盡量加, 這樣代碼更清晰
  2. this.成員方法; // 本類成員方法的調(diào)用, 能加 this 則盡量加 this
  3. this(參數(shù)),用來調(diào)用同類其他構(gòu)造方法.注意 this 語句只能定義在構(gòu)造函數(shù)的第一行,因為初始化要先執(zhí)行.

super關(guān)鍵字則和 this 差不多,都是一個引用指向自身和上一級父類罷了.

this()構(gòu)造的此類用法, 可以減少構(gòu)造的一些重復代碼

public Msg() {
  this(0, null, -1);
}

public Msg(int no) {
  this(no, null);
}

public Msg(int no, String str) {
  this(no, str);
}

對象初始化過程總結(jié)

  1. new 用到了class 文件, 所以先會找到 class文件并加載到內(nèi)存
  2. 執(zhí)行類的static {}代碼塊
  3. 在堆內(nèi)存中開辟空間,分配內(nèi)存地址
  4. 在堆內(nèi)存中建立對象的特有屬性, 并默認初始化
  5. 對屬性顯示初始化;
  6. 構(gòu)造代碼塊初始化{};
  7. 構(gòu)造函數(shù)初始化;
  8. 將內(nèi)存地址賦給棧內(nèi)存變量.

所以加載順序中: 屬性顯示初始化 早于 構(gòu)造代碼塊初始化 早于 構(gòu)造函數(shù)初始化

與之類似, 靜態(tài)屬性顯示初始化 早于 靜態(tài)構(gòu)造代碼塊初始化

代碼的組織形式-使用包

在 Java 中為了防止類、接口、枚舉和注釋等命名沖突引用了包(package)概念,包本質(zhì)上命名空間(namespace)。在包中可以定義一組相關(guān)的類型(類、接口、枚舉和注釋),并為它們提供訪問保護和命名空間管理。

package 語句定義包,package 語句應該放在源文件的第一行,在每個源文件中只能有一個包定義語句,并且 package 語句適用于所有類型(類、接口、枚舉和注釋)的文件。定義包語法格式如下:package pkg1[.pkg2[.pkg3…]];

Java API簡介: Java 中按包來組織類.包的組織采用分層結(jié)構(gòu),與文件系統(tǒng)中的目錄的組織對應一致.通常將邏輯相關(guān)的類放在同一個包中。
包將類的命名空間進行有效劃分,同一包中不能有兩個同名的類. Java 系統(tǒng)提供的類庫也成為Java API, 是系統(tǒng)提供的已實現(xiàn)的標準類的集合。

建立包

創(chuàng)建包就是在指定目錄路徑下創(chuàng)建一個子文件夾,這個包中所有類的字節(jié)碼文件將存放在該文件夾下。

方法1: 創(chuàng)建一個 test 子目錄,將源程序文件存放到該目錄,在該目錄下利用javac編譯源代碼,或者在別處編譯完程序后將字節(jié)碼文件拷貝到該目錄即可。

方法2: 采用帶路徑指示的編譯命令: 格式:javac –d destpath Point.java

編譯器將自動在 destpath 指定的目錄下建一個test子目錄,并將產(chǎn)生的字節(jié)碼文件保存到該子目錄下 。典型用法是源程序放在當前目錄下, 用如下命令編譯 javac –d . Point.java 。編譯后將在當前目錄自動創(chuàng)建 test 子目錄

包的引用

同一個包下的類之間互相引用是不需要包名的,可以直接使用。但如果類不在同一個包內(nèi),則必須要知道其所在的包。

  1. 使用類的完全限定名 :new java.util.Date()
  2. 用 import 語句加載需要使用的類。例: import java.util.Date; 然后在程序中可以直接通過類名創(chuàng)建對象, 如:new Date(); 用 import 語句加載整個包, 用*號代替類名位置。 它將加載包中的所有的類。例:import java.util.*;
  3. 使用靜態(tài)導入,它有一個 static 關(guān)鍵字,可以直接導入類的公開靜態(tài)方法和成員。例:import static java.util.Arrays.*;。但是注意靜態(tài)導入不應過度使用,否則難以區(qū)分訪問的是哪個類的代碼。

封裝性與訪問控制

Java 面向?qū)ο蟮姆庋b性是通過對成員變量和方法進行訪問控制實現(xiàn)的,訪問控制分為4個等級:私有、默認、保護和公有


Java類成員的訪問控制
  • 公有級別的關(guān)鍵字是 public,公有級別的成員變量和方法可以在任何場合被直接訪問,是最寬松的一種訪問控制等級。
  • 保護級別的關(guān)鍵字是 protected,保護級別在同一包中完全與默認訪問級別一樣,但是不同包中子類能夠繼承父類中的 protected 變量和方法,這就是所謂的保護級別,“保護”就是保護某個類的子類都能繼承該類的變量和方法。
  • 默認級別沒有關(guān)鍵字,也就是沒有訪問修飾符,默認級別的成員變量和方法,可以在其所在類內(nèi)部和同一個包的其他類中被直接訪問,但在不同包的類中則不允許直接訪問。
  • 私有級別的關(guān)鍵字是 private,私有級別的成員變量和方法只能在其所在類的內(nèi)部自由使用,在其他的類中則不允許直接訪問。

提示 訪問類成員時,在能滿足使用的前提下,應盡量限制類中成員的可見性,訪問級別順序是:私有級別→默認級別→保護級別→公有級別。

Jar 包

為方便使用第三方代碼,也為了方便我們寫的代碼給其他人使用,各種程序語言大多有打包的概念,打包的一般不是源代碼,而是編譯后的代碼。打包將多個編譯后的文件打包為一個文件,方便其他程序調(diào)用。

在Java中,編譯后的一個或多個包的Java class文件可以打包為一個文件,Java中打包命令為jar,打包后的文件擴展名為.jar,一般稱之為jar包。

可以使用如下方式打包,首先到編譯后的java class文件根目錄,然后運行如下命令:
jar -cvf hello.jar <最上層包名>

程序的編譯與鏈接

從Java 源代碼到運行的程序,有編譯和鏈接兩個步驟。編譯是將源代碼文件變成擴展名是.class的一種字節(jié)碼,這個工作一般是由 javac 命令完成的。鏈接是在運行時動態(tài)執(zhí)行的,.class 文件不能直接運行,運行的是Java虛擬機,虛擬機聽起來比較抽象,執(zhí)行的就是 Java 命令,這個命令解析 .class文件,轉(zhuǎn)換為機器能識別的二進制代碼,然后運行。所謂鏈接就是根據(jù)引用到的類加載相應的字節(jié)碼并執(zhí)行。

Java編譯和運行時,都需要以參數(shù)指定一個classpath,即類路徑。類路徑可以有多個,對于直接的class文件,路徑是class文件的根目錄;對于jar包,路徑是jar包的完整名稱(包括路徑和jar包名)。

總結(jié)來說,import 是編譯時概念,用于確定完全限定名,在運行時,只根據(jù)完全限定名尋找并加載類,編譯和運行時都依賴類路徑,類路徑中的 jar 文件會被解壓縮用于尋找和加載類。

對象銷毀

對象不再使用時應該銷毀。C++ 語言對象是通過 delete 語句手動釋放,Java語言對象是由垃圾回收器(Garbage Collection)收集然后釋放,程序員不用關(guān)心釋放的細節(jié)。自動內(nèi)存管理是現(xiàn)代計算機語言發(fā)展趨勢,例如:C# 語言的垃圾回收,Objective-C 和 Swift 語言的 ARC(內(nèi)存自動引用計數(shù)管理)。

垃圾回收器(Garbage Collection)的工作原理是:當一個對象的引用不存在時,認為該對象不再需要,垃圾回收器自動掃描對象的動態(tài)內(nèi)存區(qū),把沒有引用的對象作為垃圾收集起來并釋放。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Java 簡介 Java是由Sun Microsystems公司于1995年5月推出的Java面向?qū)ο蟪绦蛟O(shè)計...
    子非魚_t_閱讀 4,550評論 1 44
  • 大年初一開始,寫了一個正月,近4萬字,好快! 小時候?qū)懽魑慕?jīng)常用時光似箭,日月如梭,現(xiàn)在一回頭才能真切的體會到它的...
    崴崴一笑閱讀 259評論 0 1
  • 1、如果不是為了繁衍,其實男人會更愿意和男人呆在一起? 前段時間聽到兩個男同事在辦公室吐槽和女朋友相處的種種,...
    Too茜茜閱讀 519評論 0 2

友情鏈接更多精彩內(nèi)容