Java读书笔记05 类与对象
本文為java中對象與類等的基本知識(shí),包括方法、構(gòu)造、析構(gòu)、靜態(tài)域、初始化、包、路徑等。
對象與對象變量
在Java中,任何對象變量的值都是對存儲(chǔ)在另外一處的一個(gè)對象的引用。new操作符的返回值也是一個(gè)引用。
可以把Java中的數(shù)據(jù)類型分為兩類,一類是基本數(shù)據(jù)類型,即前面提到的8種基本數(shù)據(jù)類型(4種整型,2種實(shí)數(shù),1種字符,1種布爾);另一類是引用類型(reference type)。
下列語句:
Date deadline = new Date();
有兩個(gè)部分。表達(dá)式new Date()構(gòu)造了一個(gè)Date類型的對象,并且它的值是對新創(chuàng)建對象的引用,這個(gè)引用被存儲(chǔ)在變量deadline中。
可以顯示地將對象變量設(shè)置為空(null)
應(yīng)該將Java的對象變量看作是C++的對象指針。
引用類型是用在對象上的,一個(gè)對象可以被多個(gè)引用所指向,但同一時(shí)刻,每個(gè)引用只能指向唯一的一個(gè)對象。如果一個(gè)對象被多個(gè)引用所指向,那么無論哪個(gè)引用對對象屬性進(jìn)行了修改,都會(huì)反映到其他的引用當(dāng)中。
C++中沒有空引用,并且引用不能被賦值。
所有的Java對象都存儲(chǔ)在堆中。變量包含的是指向堆對象的指針。引用存放的是對象的地址。
在Java中使用clone方法來獲得對象的完整拷貝。
?
用戶自定義類
在一個(gè)源文件中,只能有一個(gè)公有類,但可以有任意數(shù)目的非公有類。
源文件名必須與公有類的名字相匹配。
當(dāng)編譯源程序時(shí)所有使用到的類都會(huì)被編譯。
?
方法
Java中所有的方法都必須在類的內(nèi)部定義,但并不像C++那樣把類內(nèi)部定義的方法作為inline,是否將某個(gè)方法作為內(nèi)聯(lián)方法是Java虛擬機(jī)的任務(wù)。
若需要返回一個(gè)可變數(shù)據(jù)域的拷貝,就應(yīng)該使用clone。
?
構(gòu)造器
構(gòu)造器即構(gòu)造函數(shù),工作方式與C++基本相同。但是所有的Java對象都是在堆中構(gòu)造的,構(gòu)造器總是伴隨著new操作符一起使用。
如果在編寫一個(gè)類時(shí)沒有編寫構(gòu)造器,系統(tǒng)就會(huì)提供一個(gè)默認(rèn)構(gòu)造器(默認(rèn)構(gòu)造器是指沒有參數(shù)的構(gòu)造器)。系統(tǒng)提供的這個(gè)默認(rèn)構(gòu)造器會(huì)將所有的實(shí)例域設(shè)置為默認(rèn)值。
如果類中至少提供了一個(gè)構(gòu)造器,但是沒有提供默認(rèn)的構(gòu)造器,那么在構(gòu)造對象時(shí)若不提供構(gòu)造參數(shù)就視為不合法。用戶如果希望不提供參數(shù)時(shí),所有域擁有默認(rèn)的值,可以提供一個(gè)空的默認(rèn)構(gòu)造器。
如果構(gòu)造器的第一個(gè)語句形如this(…),那么這個(gè)構(gòu)造器將調(diào)用同一個(gè)類的另一個(gè)構(gòu)造器。
注意:在C++中一個(gè)構(gòu)造器不能調(diào)用另一個(gè)構(gòu)造器,必須將抽取出的公共初始化代碼編寫成一個(gè)獨(dú)立的方法。
?
方法參數(shù)
?
隱式參數(shù)與顯式參數(shù)
每一個(gè)方法中,this表示隱式參數(shù),表示對象。
顯式參數(shù)是列在方法括號(hào)中的數(shù)值。
?
方法參數(shù)的傳遞
C++有值調(diào)用和引用調(diào)用,引用參數(shù)標(biāo)有&符號(hào)。
Java程序設(shè)計(jì)語言使用值調(diào)用,方法得到的是參數(shù)值的一個(gè)拷貝。
即對于Java中的方法參數(shù)傳遞,無論傳遞的是原生數(shù)據(jù)類型,還是引用類型,統(tǒng)一是傳值(pass by value)。
對于基本數(shù)據(jù)類型來說,方法中的變量被初始化為實(shí)參的一個(gè)拷貝,方法結(jié)束后,原來的在方法外部的變量并不改變,而方法中的變量不再使用。
對于對象引用來說,方法中的變量被初始化為對象引用值的拷貝,即一個(gè)對象的引用。方法可以改變一個(gè)對象參數(shù)的狀態(tài)。
但是認(rèn)為Java對對象采用的是引用調(diào)用,這種理解是不對的。如果將兩個(gè)對象的引用的拷貝在方法中交換,這樣并不能夠真的交換這兩個(gè)對象。這說明一個(gè)方法不能讓對象參數(shù)引用一個(gè)新的對象。
?
靜態(tài)域與靜態(tài)方法
?
靜態(tài)域:
如果將域定義為static,那么每個(gè)類中只有一個(gè)這樣的域。而每一個(gè)對象對于所有的實(shí)例域卻都有一份自己的拷貝。
?
靜態(tài)常量:
public static final double PI=3.1415926535;
public static final PrintStream out=…;
?
靜態(tài)方法:
靜態(tài)方法是不能向?qū)ο髮?shí)施操作的方法。即沒有隱式的參數(shù)this。
main方法是一個(gè)靜態(tài)方法,因?yàn)樵趩?dòng)程序的時(shí)候還沒有任何一個(gè)對象。
(每個(gè)類可以有個(gè)main方法,這是對類進(jìn)行單元測試時(shí)一個(gè)常用技巧。)
因?yàn)殪o態(tài)方法不能操作對象,所以不能在靜態(tài)方法中訪問實(shí)例域。但是靜態(tài)方法可以訪問自身類中的靜態(tài)域。
以下兩種情況使用靜態(tài)方法:
1.當(dāng)一個(gè)方法不需要訪問對象狀態(tài),所有參數(shù)都是通過顯示參數(shù)提供的。
2.當(dāng)一個(gè)方法只需要訪問類的靜態(tài)域。
?
顯式域初始化
在執(zhí)行構(gòu)造器之前先進(jìn)行賦值,當(dāng)一個(gè)類的所有構(gòu)造器都希望將相同的值賦予某個(gè)特定的實(shí)例域時(shí),這種方法特別有用。
初始值不一定是常量,域可以調(diào)用方法來進(jìn)行初始化。
?
靜態(tài)初始化:
對靜態(tài)域進(jìn)行初始化可以將代碼放在一個(gè)塊中,并標(biāo)記關(guān)鍵字static。在類第一次加載的時(shí)候,將會(huì)進(jìn)行靜態(tài)域的初始化,與實(shí)例域一樣,靜態(tài)域的默認(rèn)初始值為false或null,除非將它們顯式設(shè)置成其他值。
所有的靜態(tài)初始化語句以及靜態(tài)初始化塊 都將按照類定義中出現(xiàn)的順序執(zhí)行。
?
對象析構(gòu)與finalize方法
Java有自動(dòng)的垃圾回收器,不需要人工回收內(nèi)存,所以不支持析構(gòu)器。
當(dāng)使用了內(nèi)存之外的其他資源,如文件或使用了系統(tǒng)資源的另一個(gè)對象的句柄,在這種情況下,當(dāng)資源不再需要的時(shí)候,將其回收和再利用十分重要。
可以為任何一個(gè)類添加finalize方法,該方法將在垃圾回收器清除對象之前被調(diào)用。在實(shí)際應(yīng)用中,不要使用finalize方法回收任何短缺的資源,這是因?yàn)楹茈y知道這個(gè)方法什么時(shí)候才能夠被調(diào)用。
如果某個(gè)資源需要在使用完畢后立刻被關(guān)閉,就需要人工管理。提供一個(gè)類似dispose或close這樣的方法,用來做相應(yīng)的清理。如果一個(gè)類使用了這樣的方法,當(dāng)對象不再使用時(shí)一定要調(diào)用它。
?
包
package將類組織起來。
所有標(biāo)準(zhǔn)的Java包都處于java和javax包層次中。
使用包的主要原因是確保類名的唯一性,Sun公司建議將公司的英特網(wǎng)域名以逆序的形式作為包名,并且對于不同的項(xiàng)目使用不同的子包。
包嵌套的唯一目的是管理唯一的名字。從編譯器的角度來看,嵌套的包之間沒有任何關(guān)系。每一個(gè)都擁有獨(dú)立的類集合。
?
類的導(dǎo)入
一個(gè)類可以使用所屬包中的所有類,以及其他包中的公有類。
訪問另一個(gè)包中的共有類有兩種方式:
1.在每個(gè)類名之前添加完整的包名。如:
java.util.Date today = new java.util.Date();
2.使用import語句(位于源文件頂部,package語句的后面)導(dǎo)入一個(gè)特定的類或者整個(gè)包。如:
import java.util.*;
還可以導(dǎo)入一個(gè)包中的特定類:
import java.util.Date;
?
靜態(tài)導(dǎo)入
import語句不僅可以導(dǎo)入類,還增加了導(dǎo)入靜態(tài)方法和靜態(tài)域的功能。
import static java.lang.System.*;
?
將類放入包中
要想將一個(gè)類放入包中,就必須將包的名字放在源文件的開頭。如:
package com.horstmann.corejava;
如果沒有在源文件中放置package語句,那么這個(gè)源文件中的類就被放置在一個(gè)默認(rèn)包中,默認(rèn)包是一個(gè)沒有名字的包。
?
虛擬機(jī)如何定位類
類存儲(chǔ)在文件系統(tǒng)的子目錄中,類的路徑必須與包名匹配。
另外,還可以利用JAR實(shí)用程序?qū)㈩愇募砑拥綒w檔文件中。在一個(gè)歸檔文件中,可以包含多個(gè)類文件和子目錄,這樣既可以節(jié)省又可以改善性能。
類路徑所列出的目錄和歸檔文件是搜尋類的起始點(diǎn),是所有基目錄的集合,基目錄中的子目錄可以用于包含類文件。
設(shè)置類路徑的方法取決于編譯環(huán)境。如果使用JDK,那么就有兩種選擇:為編譯器和字節(jié)碼解釋器指定-classpath選項(xiàng),或者設(shè)置CLASSPATH環(huán)境變量。
具體的設(shè)置細(xì)節(jié)取決于操作系統(tǒng)。
句點(diǎn).表示當(dāng)前目錄,Windows環(huán)境中,各基目錄以分號(hào);間隔。
由于運(yùn)行時(shí)庫文件(在jre/lib與jre/lib/ext目錄下的rt.jar和一些其他的JAR文件)會(huì)被自動(dòng)地搜索,所以不必將它們顯式地列在類路徑中。
為編譯器設(shè)置類路徑:
javac –classpath …
也可以用-cp代替-classpath
javac編譯器總是在當(dāng)前目錄中查找文件,而java解釋器僅在類路徑中有.目錄的時(shí)候,才查看當(dāng)前目錄。
?
包作用域
標(biāo)記為public的部分可以被任意的類使用;
標(biāo)記為private的部分只能被定義它們的類使用。
如果沒有指定public或private,那么這個(gè)部分可以被同一個(gè)包中的所有方法訪問。
總結(jié)
以上是生活随笔為你收集整理的Java读书笔记05 类与对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中压缩、解压缩(tar/zip
- 下一篇: Java编程中写出好代码的建议