1. 程式人生 > 實用技巧 >java-09面向物件(五)

java-09面向物件(五)

一、關鍵字 static

1.static關鍵字的使用

static可以用來修飾:屬性、方法、程式碼塊、內部類

static修飾屬性:靜態變數(或類變數)

●我們建立了類的多個物件,多個物件共享同一個靜態變數。當通過某一個物件修改靜態變數時,會導致其他物件呼叫此靜態變數時,是修改過了的。類似於舍友有屬於自己的床,但共用一個衛生間。
●靜態變數隨著類的載入而載入。可以通過"類.靜態變數"的方式進行呼叫
●靜態變數的載入要早於物件的建立。
●由於類只會載入一次,則靜態變數在記憶體中也只會存在一份:存在方法區的靜態域中。

類變數與例項變數的記憶體解析

2.使用static修飾方法:靜態方法

●靜態方法中,只能呼叫靜態的方法或屬性。而非靜態方法中,靜態和非靜態的方法或屬性都可以呼叫
●在靜態方法中,不能使用this關鍵字、super關鍵字。
●操作靜態屬性的方法,通常設定為static的
●工具類的方法,習慣上宣告為static
●類中的常量常常宣告為static

3.單例設計模式

●設計模式是在大量的實踐中總結和理論化之後優選的程式碼結構、程式設計風格以及解決問題的思考方式。設計模免去我們自己再思考和摸索。式就像是經典的棋譜,不同的棋局,我們用不同的棋譜,”套路”
●所謂類的單例設計模式,就是採取- -定的方法保證在整個的軟體系統中,對某個類只能存在一個物件例項,並且該類只提供一個取得其物件例項的方法。如果我們要讓類在一個虛擬機器中只能產生-一個物件,我們首先必須將類的構造器的訪問許可權設定為private,這樣,就不能用new操作符在類的外部產生類的物件了,但在類內部仍可以產生該類的物件。因為在類的外部開始還無法得到類的物件,只能呼叫該類的某個靜態方法以返回類內部建立的物件,靜態方法只能訪問類中的靜態成員變數,所以,指向類內部產生的該類物件的變數也必須定義成靜態的。

案例

    package shejimoshi;
    public class SingletonTest {
	    public static void main(String[] args) {
		    Bank bank1 = Bank.getInstance();
		    Bank bank2 = Bank.getInstance();
		    System.out.println(bank1 == bank2);//true
		
		    Order order1 = Order.getInstance();
		    Order order2 = Order.getInstance();
		    System.out.println(order1 == order2);//true
	    }
    }
//餓漢式,執行緒安全,但載入時間相對較長
    class Bank{
	    //1.私有化類的構造器
	    private Bank(){
		
	    }
	    //2.內部建立類的物件,並且宣告靜態
	    private static Bank instance = new Bank();
	    //3.提供公共的靜態的方法,返回 類的物件
	    public static Bank getInstance(){
		    return instance;
	    }	
    }
    //懶漢式,延遲物件建立,但目前寫法執行緒不安全
    class Order{
	    //1.私有化類的構造器
	    private Order(){
			
	    }
	    //2.聲明當前類的物件,不初始化並且宣告靜態
	    private static Order instance = null;
	    //3.宣告public、static的返回當前類物件的方法
	    public static Order getInstance(){
		    if(instance == null){
		    	    instance = new Order();
	        	}
		    return instance;
	    }
    }

減少了系統性能開銷。

單例模式應用場景

➢網站的計數器,一般也是單例模式實現,否則難以同步。
➢應用程式的日誌應用,一般都使用單例模式實現,這一般是由於共享的日誌檔案一直處於開啟狀態,因為只能有一個例項去操作,否則內容不好追加。➢資料庫連線池的設計一般也是採用單例模式,因為資料庫連線是一種資料庫資源。
➢專案中,讀取配置檔案的類,一般也只有一個物件。沒有必要每次使用配置檔案資料,都生成一個物件去讀取。
➢Application也是單例的典型應用
➢Windows的TaskManager(工作管理員)就是很典型的單例模式
➢Windows的Recycle Bin(回收站)也是典型的單例應用。在整個系統執行過程中,回收站一直維護著僅有的一個例項。

二、程式碼塊

1.程式碼塊的作用

初始化類、物件

2.靜態程式碼塊、

static{
        //初始化類的資訊
}

●內部可以有輸出語句
●隨著類的載入而執行,而且只執行一次
●初始化類的資訊
●如果一個類中定義了多個靜態程式碼塊,則按照先後順序來執行
●靜態程式碼塊的執行要優先於非靜態程式碼塊的執行
●靜態程式碼塊內只能帶哦也靜態的屬性、靜態的方法

3.非靜態程式碼塊

{
        //對物件的屬性等進行初始化
}

●內部可以有輸出語句
●隨著物件的建立而執行
●每建立一個物件,就執行一次非靜態程式碼塊
●可以在建立物件時,對物件的屬性等進行初始化
●如果一個類中定義了多個靜態程式碼塊,則按照先後順序來執行

三、final 關鍵字

●final意為最終的,可以用來修飾類、方法、變數
●final修飾的類,不能被其他類所繼承
●final修飾的方法,表名此方法不可以被重寫
●final修飾的變數,此時的"變數"就稱為是一個常量
●final修飾屬性,可以考慮賦值的位置有:顯式初始化、程式碼塊中初始化、構造器中初始化。
●final修飾區域性變數,使用final修飾形參時,表名此形參是一個常量。不能再重新賦值。
●static final 用來修飾屬性:全域性常量

四、抽象類與抽象方法

隨著繼承層次中一個個新子類的定義,類變得越來越具體,而父類則更一般,更通用。類的設計應該保證父類和子類能夠共享特徵。有時將一個父類設計得非常抽象,以至於它沒有具體的例項,這樣的類叫做抽象類。

1.abstract 關鍵字的使用

abstract 意為抽象的,可以用來修飾類、方法。

abstract 修飾類:抽象類

abstract class 類名{
    //空參構造器;
    //帶參構造器
    //方法
}

●此類不能例項化
●抽象類中一定有構造器,便於子類例項化時呼叫(涉及子類物件例項化的全過程)
●開發中,都會提供抽象類的子類,讓子類物件例項化,完成相關的操作

abstract修飾方法:抽象方法

public abstract void 方法名();

●抽象方法只有方法的宣告,沒有方法體
●包含抽象方法的類,一定是一個抽象類。反之,抽象類中可以沒有抽象方法。
●若子類重寫了父類中的所有抽象方法後,此子類方可例項化
●若子類沒有重寫父類中的所有的抽象方法,則此子類也是一個抽象類,需要用abstract修飾

abstract 使用方法上的注意點

●abstract 不能用來修飾:屬性、構造器等結構。
●abstract 不能用來修飾私有方法、靜態方法、final的方法、final的類

多型的應用:模板方法設計模式

抽象類體現的就是一種模板模式的設計,抽象類作為多個子類的通用模板,子類在抽象類的基礎上進行擴充套件、改造,但子類總體上會保留抽象類的行為方式。

解決的問題:

➢當功能內部一部分實現是確定的,一部分實現是不確定的。這時可以把不確定的部分暴露出去,讓子類去實現。
➢換句話說,在軟體開發中實現一個演算法時,整體步驟很固定、通用,這些步驟已經在父類中寫好了。但是某些部分易變,易變部分可以抽象出來,供不同子類實現。這就是一種模板模式

模板方法設計模式是程式設計中經常用得到的模式。各個框架、類庫中都有他的影子,比如常見的有:

●資料庫訪問的封裝
●Junit單元測試
●JavaWeb的Servlet中 關於doGet/doPost方法呼叫
●Hibernate中 模板程式
●Spring中 JDBC Temlate、Hibernate Template等

五、介面

1.概念

●一方面,有時必須從幾個類中派生出一個子類,繼承它們所有的屬性和方法。但是,Java不支援多重繼承。有了介面,就可以得到多重繼承的效果。
●另一方面,有時必須從幾個類中抽取出一些共同的行為特徵,而它們之間又沒有繼承的關係,僅僅是具有相同的行為特徵而已。例如:滑鼠、鍵盤、印表機、掃描器、攝像頭、充電器、MP3機、手機、數碼相機、行動硬碟等都支援USB連線。
●介面就是規範,定義的是一組規則,體現了現實世界中“如果你是/要...則必須能...”的思想。繼承是一個"是不是"的關係,而介面實現則是"能不能"的關係。
●介面的本質是契約,標準,規範,就像我們的法律一樣。制定好後大家都要遵守。

2.介面的使用

●介面用 interface 定義
●Java中,介面和類是並列的兩個結構
●介面中不能定義構造器,意味著介面不能例項化
●Java開發中,介面通過讓類去實現(implements)的方式來使用,如果實現類覆蓋了介面中的所有抽象方法,則此實現類就可以例項化。如果實現類沒有覆蓋介面中的所有抽象方法,則此實現類仍為一個抽象類。

Java類可以實現多個介面 ---> 彌補了Java單繼承性的侷限性

格式:class AA extends BB implements CC,DD,EE

●介面與介面之間可以繼承,而且可以多繼承。

JDK7以前:只能定義全域性變數和抽象方法

全域性常量:public static final... ,書寫時可以省略不寫
抽象方法:public abstract...

JDK8:除了定義全域性常量和抽象方法之外,還可以定義靜態的方法、預設方法

●介面中定義的靜態方法,只能通過介面來呼叫。
●通過實現類的物件,可以呼叫介面中的預設方法。
●如果子類(或實現類)繼承的父類和實現的介面中聲明瞭同名同參數的方法,那麼子類在沒有重寫此方法的情況下,預設呼叫的是父類中的同名同參數的方法。 --> 類優先原則
●如果實現類實現了多個介面,而這個介面中定義了同名同參數的預設方法,那麼在實現類中沒有重寫此方法的情況下,報錯。
●在子類(或實現類)的方法中呼叫父類、介面中被重寫的方法。super.xx(),interface_name.super.xx()

3.介面的應用:工廠模式

工廠模式實現了建立者與呼叫者的分離,即將建立物件的具體過程遮蔽隔離起來,達到提高靈活性的目的。

六、內部類的使用

1.概念

●Java中允許將一個類A宣告在另一個類B中,則類A就是內部類,類B稱為外部類
●成員內部類:一方面,作為一個類可以定義屬性、方法、構造器等,可以被final修飾,表示此類不能被繼承,可以被abstract修飾;另一方面,可呼叫外部類的結構,可被static修飾,可以被4中不同的許可權修飾。
●區域性內部類(方法內、程式碼塊內、構造器內)。