- 對象與類:
1.Date t=new Date(); 有2部分,new Date()構造了一個Date類型的對象(Java對象都存儲在堆中),而對這個對象的引用存儲在對象變量t中。Java對象變量與C++的引用不同,在C++沒有空引用,并且應用不能被指派。可以将java的對象變量看作C++的對象指針。Java中的null引用對應C++中的NULL指針。
2.靜态方法是一種不能向對象實施操作的方法,是以不能在靜态方法中通路域。
在兩種情況下使用靜态方法:
1).一個方法不需要通路對象狀态,其所需參數都是通過形參提供
2).一個方法隻需要通路類的靜态域。
3.不要在getXX方法中傳回可變對象的引用。如:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzLcFUT0Y0NSpEd45mMM9kZTZXUuRUYpVDbIRjNilWOuFmSCFXZZRUb6RTRDVWQqpURhJlQxNFeqFWaQ9CXjlGcfJXYid2Lc52YuMWawFnLjdWdvw1LcpDc0RHaiojIsJye.jpg)
private Date date;
原因:破壞封裝性,令一變量如newDate=A.getDate(),則newDate就可以修改Date類的私有域。
若要傳回引用,應該首先進行克隆(clone): return (Date)date.clone()。
- 靜态域與靜态方法
1.靜态域又名類變量,即所有執行個體共享這一個變量;
2.靜态方法是一種不能向對象實施操作的方法,是以不能在靜态方法中通路執行個體域,但它可以通路類中的靜态域。
為什麼NumberFormat類不利用構造器完成這些操作呢?兩個原因:
1).無法命名構造器。構造器的名稱必須與類名相同。但這裡,希望得到的貨币執行個體和百分比執行個體采用不同的名字;
2).當使用構造器時,無法改變所構造的對象類型。而Factory方法将傳回一個DecimalFormat類對象(NumberFormat的子類).
不管是靜态變量,靜态方法,還是靜态塊,都是在類加載的時候執行的;而初始化塊等是類執行個體化時調用的。
一個類的運作,JVM做會以下幾件事情 1、類裝載 2、連結 3、初始化 4、執行個體化;而初始化階段做的事情是初始化靜态變量和執行靜态方法等的工作。
- 方法參數(形參)
一個方法不能修改一個基本資料類型的參數;
一個方法可以改變一個對象參數的狀态(形參為對象變量);
一個方法不能實作讓對象參數引用一個新的對象。
注:Java重載(傳回類型不是方法簽名的一部分).
多态:一個對象變量可以引用多種實際類型的現象
動态綁定:在運作時能自動選擇調用哪個方法的現象。
1.對于變量(不管靜态變量還是執行個體變量),都是靜态綁定,靜态綁定對應聲明的對象變量類型。(編譯時) 2.而對于方法,private、static、final方法是靜态綁定,其他的都為動态綁定,動态綁定對應對象類型。(運作時)即Father f=new Son(); f.field和f.static_method()調用超類即Father的成員,要通路子類變量,可以用getX()和setX()方法。其他形式則調用子類即Son的成員。 注:超類方法為private時編譯無法通過。 3.在覆寫一個方法時,子類方法不能低于超類方法的可見性。 |
- 抽象類
1.包含一個或多個抽象方法的類本身必須被聲明為抽象的;
2.除了抽象方法之外,抽象類還可以包含具體資料和具體方法;
3.擴充抽象類時,若隻定義超類的部分抽象方法,則子類也應為抽象類;若全部定義,則子類不是抽象的。
4.抽象類不能執行個體化。是以抽象類的對象變量不能引用抽象子類的對象。
注:Abstract[] a=new Abstract[]; //聲明抽象對象數組,并非執行個體化。
- Object重要方法
1.equals方法
在Object中equals比較的是引用(即記憶體位址),等同于==;是以,在沒有覆寫equals方法的類中,比較的是引用;
而覆寫equals方法的類,根據具體實作來判斷,一般比較的是内容,如String類的equals方法。==則始終是位址。
更詳細的參考下圖。
2.hashCode
散列碼(hash code)是由對象導出的一個整數值,并且它是沒有規律的。不同的對象散列碼一般不同。如果重新定義equals
方法,就必須重新定義hashcode方法,以便使用者可以将對象插入到散清單中。Equals與hashCode的定義必須一緻:如果
x.equals(y)傳回true,那麼x.hashCode()就必須與y.hashCode()具有相同的值。
接口:
1.接口中的所有方法自動地具有public屬性;接口不能含有執行個體域(final常量除外,且常量屬性自動為public static final),
也不能在接口中實作方法。
2.同繼承一樣,實作接口時,必須提供不低于上面一層(接口或超類)的通路權限。是以必須把方法聲明為public。
3.同抽象類一樣,接口也不能執行個體化,可以聲明接口變量但必須引用實作了接口的類對象。
接口與抽象類:每個類隻能擴充一個(抽象)類,而可以實作多個接口(多繼承)
克隆
Object類中clone是protected方法,對本包和所有的子類(包括包外)可見。但是用自己編寫的類調用clone方法測試了一下,
運作時抛出CloneNotSupportedException異常,且說明了clone是本地方法。為什麼不能直接調用???原因就在下面:
必須實作Cloneable接口,并且可以不提供clone方法。
部分代碼示例:
輸出結果: A A
淺拷貝:預設的克隆操作,它并沒有克隆包含在對象中的内部對象。但是若執行個體域中的對象是不可變或者是基本類型
(不需要重定義clone方法,但推薦重定義并調用Object的clone:super.clone());
深拷貝:在淺拷貝的基礎上,克隆對象中的内部對象(必須重定義clone方法)。
要想一個類可以被clone,必須滿足兩點:
第一,它必須實作了Cloneable接口,否則會抛出CloneNotSupportedException異常;
第二,它必須提供一個public的clone方法,也就是重寫Object.clone()方法,否則編譯不能通過。
另外,對于存在可變域的類,在clone方法中需要對這些可變域進行拷貝(深拷貝)。
注:Object 類本身不實作接口 Cloneable,是以在類為 Object 的對象上調用 clone 方法将會導緻在運作時抛出異常。
Cloneable接口并沒有定義任何方法,它隻是作為一個标記,表面要進行克隆處理。
内部類:
1.成員内部類
簡述:作為外部類的一個成員存在,與外部類的屬性、方法并列。可以在外部類方法中執行個體化内部類對象來通路内部類方法。
成員内部類的對象有一個隐式引用,它引用了執行個體化該内部對象的外部類對象。通過這個指針,可以通路外部類對象的任何域和
方法。 但内部類不能定義靜态成員(靜态内部類除外)。
特殊文法:
外部類引用表達式OuterClass.this;
内部對象構造器:outerObject.new InnerClass(parameters);
注: 在外部類的作用域之外,則可以用OuterClass.InnerClass來引用内部類。
2.匿名内部類
文法格式:
SuperType是接口,則内部類就要實作這個接口;SuperType是一個類,則内部類就要擴充它。
3.靜态内部類:使用内部類隻是為了隐藏,可以将内部類聲明為static,取消對外部類的引用。可以将它看作外部類的靜态成員。
4.局部内部類:
在一個方法中定義局部類。不能用public或private通路說明符進行聲明。它的作用域被限定在聲明這個局部類的塊中。
并且除了這個方法之外,沒有其他的方法知道局部内 部類的存在,但是可以用外部類對象調用該方法來間接通路内部類。在
内部類中可以通路内部類的局部變量(即方法内的變量),但是變量必須是final的。