1. 程式人生 > >子父類繼承問題,陣列反射,單例設計

子父類繼承問題,陣列反射,單例設計

繼承:
父類(SuperClass)和 子類(SonClass)。
父類的非私有化屬性和方法可以預設繼承到子類。
Class Son extends Father{}
而如果父類中的私有方法被子類呼叫的話,則編譯報錯。

父類的構造方法子類不可以繼承,更不存在覆蓋的問題。(非構造方法可以)
如果子類訪問父類的構造方法,則在編譯的時候提示訪問不到該方法。
JAVA中不允許多繼承,一個類有且只有一個父類(單繼承)。
JAVA的資料結構為樹型結構,而非網狀。(JAVA通過介面和內部類實現多繼承)

方法的覆蓋(overriding)
方法的過載並不一定是在一個類中:子類可以從父類繼承一個方法,也可以定義一個同名異參的方法,也稱為overloading。
當子類從父類繼承一個無參方法,而又定義了一個同樣的無參方法,則子類新寫的方法覆蓋父類的方法,稱為覆蓋。(注意返回值型別也必須相同,否則編譯出錯。)
如果方法不同,則成過載。

對於方法的修飾詞,子類方法要比父類的方法範圍更加的寬泛。父類為public,那麼子類為private則出現錯誤。
之所以構造方法先執行父類再執行子類是因為構造方法是無法覆蓋的。
以下範圍依次由嚴到寬:
private :本類訪問;
default :表示預設,不僅本類訪問,而且是同包可見。
Protected:同包可見+不同包的子類可見
Public :表示所有的地方均可見。

當構造一個物件的時候,系統先構造父類物件,再構造子類物件。
構造一個物件的順序:(注意:構造父類物件的時候也是這幾步)
①        遞迴地構造父類物件;
②        順序地呼叫本類成員屬性賦初值語句;
③        本類的構造方法。

Super()表示呼叫父類的構造方法。
Super()也和this一樣必須放在第一行。
This()用於呼叫本類的構造方法。
如果沒有定義構造方法,那麼就會呼叫父類的無參構造方法,即super()。

要養成良好的程式設計習慣:就是要加上預設的父類無參的構造方法。
=========================================-=========================================-=========================================-
int,double,long這些都是基本資料型別,不具備物件的特性。一個物件就有屬性和行為,但是基本資料型別沒有。
java中的Integer就是int的包裝類,它定義的變數就是物件型別了,有屬性和行為。

int.class只是int 的 Class物件,也就是說int.class是一個Class物件
API幫助文件中所描述的:
Class 類的例項表示正在執行的 Java 應用程式中的類和介面。列舉是一種類,註釋是一種介面。每個陣列屬於被對映為 Class 物件的一個類,所有具有相同元素型別和維數的陣列都共享該 Class 物件。基本的 Java 型別(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也表示為 Class 物件。

陣列反射
如果因為某種原因,並不確定引數或物件是不是陣列,可以檢索物件的 Class 物件並詢問它。 Class 類的 isArray() 方法將會告訴您。一旦知道擁有了一個數組,就可以詢問 Class 的 getComponentType() 方法,實際擁有的是什麼型別的陣列。如果 isArray() 方法返回 false,那麼 getComponentType() 方法返回空。否則返回元素的 Class 型別。如果陣列是多維的,可以遞迴呼叫 isArray() 。它將仍只包含一個 component 型別。此外,可以用在 java.lang.reflect 包裡找到的 Array 類的 getLength() 方法獲取陣列的長度。

為了演示,清單 2-3 顯示了傳遞給 main() 方法的引數是 java.lang.String 物件的陣列,其中陣列長度由命令列引數的個數確定:

清單 2-3. 使用反射檢查陣列型別和長度

public class ArrayReflection {
	public static void main (String args[]){
		printType(args);
	}
	
	private static void printType (Object object){
		Class type = object.getClass();
		if (type.isArray()) {
			Class elementType = type.getComponentType();
			System.out.println("Array of: " + elementType);
			System.out.println(" Length: " + Array.getLength(object));
		}
	}
}
注意:如果 printType() 用於前面定義的 buttons 和 components 變數呼叫,每個都會表明陣列是 java.awt.Button 型別。

如果不使用 isArray() 和 getComponentType() 方法,而且試圖列印陣列的 Class 型別,將獲得一個包含 [ ,後面跟著一個字母和類名(如果是個基本資料型別就沒有類名)的字串。

例如,如果試圖打印出上述 printType() 方法中的型別變數,將獲得 class [Ljava.lang.String; 作為輸出。

除了詢問一個物件是不是陣列以及是什麼型別的陣列之外,還可以在執行時用 java.lang.reflect.Array class 建立陣列。這對於建立一般實用例程非常有用,這些例程執行陣列任務,比如將大小加倍。(我們會立即回到那一點。)

要建立一個新陣列,使用 Array 的 newInstance() 方法,它有兩種變化形式。對於一維陣列通常將使用較簡單版本,它的執行方式如語句 new type [length] 所示,並作為物件返回陣列: public static Object newInstance(Class type, int length) 。例如,下面的程式碼建立一個五個整數空間大小的陣列:

int array[] = (int[])Array.newInstance(int.class, 5);

注意:要為基本資料型別指定 Class 物件,只要在基本資料型別名末尾新增 .class 就可以了。還可以使用包裝類中的 TYPE 變數,如 Integer.TYPE。

newInstance() 方法中的第二種變化形式要求維數被指定為整型陣列: public static Object newInstance(Class type,int dimensions []) 。在建立一個一維陣列的最簡單的情況下,將建立只有一個元素的陣列。換句話說,如果要建立包含五個整數的相同陣列,需要建立一個單個元素 5 的陣列並傳遞到 newInstance() 方法,而不是傳遞整數值 5。

int dimensions[] = {5};
int array[] = (int[])Array.newInstance(int.class, dimensions);

在只需要建立一個矩形陣列的時候,就可以將每個陣列長度填充到這個 dimensions 陣列中。例如,下面的程式碼與建立一個 3 X 4 的整數陣列等價。

int dimensions[] = {3, 4};
int array[][] = (int[][])Array.newInstance(int.class, dimensions);

但是,如果需要建立一個非矩形陣列,將需要多次呼叫 newInstance() 方法。第一次呼叫將定義外部陣列的長度,並獲得一個看上去很古怪的類引數([].class 適用於元素為 float 型別的陣列)。每個後續呼叫將定義每個內部陣列的長度。例如,下面演示瞭如何建立一個元素為 float 型別的陣列,其內部陣列的大小設定像一組保齡球瓶:第一排一個元素,第二排兩個,第三排三個,第四排四個。為了將這種情況形象化,讓我們回顧早先在圖 2-4 展示的三角形陣列。
float bowling[][] = (float[][])Array.newInstance(float[].class, 4);
for (int i=0; i<4; i++) {
	bowling = (float[])Array.newInstance(float.class, i+1);
}
一旦在執行時建立了陣列,還可以獲取和設定陣列元素。不過通常不會這樣做,除非鍵盤上的方括號鍵失靈或者在動態的程式設計環境(程式被建立時陣列名未知)中工作。 如表 2-2 所示, Array 類有一系列的 getter 和 setter 方法用來獲取和設定陣列元素。使用什麼方法取決於處理的陣列型別。

表 2-2. 陣列 getter 和 setter 方法
Getter 方法				Setter 方法
get(Object array, int index)		set(Object array, int index, Object value)
getBoolean(Object array, int index)	setBoolean(Object array, int index, boolean value)
getByte(Object array, int index)	setByte(Object array, int index, byte value)
getChar(Object array, int index)	setChar(Object array, int index, char value)
getDouble(Object array, int index)	setDouble(Object array, int index, double value)
getFloat(Object array, int index)	setFloat(Object array, int index, float value)
getInt(Object array, int index)		setInt(Object array, int index, int value)
getLong(Object array, int index)	setLong(Object array, int index, long value)
getShort(Object array, int index)	setShort(Object array, int index, short value)

注意:可以一直使用 get() 和 set() 方法。如果陣列是一個基本資料型別陣列, get() 方法的返回值或 set() 方法的值引數將被包裝到用於基本資料型別的包裝類中,像裝著一個 int 陣列的 Integer 類那樣。

================================================

什麼時候需要使用單例設計?

單例模式:解決了一個類在記憶體中只能存在一個物件
使用單例模式總結就是以下三點:
(1)控制資源的使用,通過執行緒同步來控制資源的併發訪問;
(2)控制例項產生的數量,達到節約資源的目的。
(3)作為通訊媒介使用,也就是資料共享,它可以在不建立直接關聯的條件下,讓多個不相關的兩個執行緒或者程序之間實現通訊
比如:資料庫連線池的設計一般採用單例模式,資料庫連線是一種資料庫資源