天天看點

static、final、private方法的差別

public class FinalAndPrivate {
	@SuppressWarnings("all")
	public static void main(String[] args) {
		
		Parent p = new Parent();
		p.call();
		p.call2();
		p.print();
		p.staticMethod();
		System.out.println("=====================================");
		
		Parent psub = new FAP();
		psub.call();
		psub.call2();
		psub.print();
		psub.staticMethod();
		System.out.println("=====================================");
		
		FAP fap = new FAP();
		fap.call();
		fap.call2();
		fap.print();
		fap.print("hello world");
		fap.staticMethod();
	}

}
class Parent {
	
	private void show() {
		System.out.println("super.show() is calling...");
	}
	public void call() {
		System.out.println("super.call() is calling...");
		this.show();
	}
	
	private final void show2() {
		System.out.println("super.show2() is calling...");
	}
	public void call2() {
		System.out.println("super.call2() is calling...");
		this.show2();
	}
	
	public final void print() {
		System.out.println("super.print() is calling...");
	}
	
	public static void staticMethod() {
		System.out.println("super.staticMethod() is calling...");
	}
}
class FAP extends Parent {
	
	private void show() {
		System.out.println("FAP.show() is calling...");
	}
	//override
	public void call() {
		System.out.println("FAP.call() is calling...");
		this.show();
		//編譯錯誤,super.show() is not visible
		//super.show();
	}
	
	public void show2() {
		System.out.println("FAP.show2() is calling...");
	}
	
	/* 
	 * 編譯錯誤,不能覆寫(override)超類的final方法
	public final void print() {
		System.out.println("super.print() is calling...");
	}*/
	//可以重載(overload)
	public final void print(String str) {
		System.out.println("FAP.print(String str) is calling... message = " + str);
	}
	
	/* 
	 * 編譯錯誤,不能覆寫(override)超類的static方法
	public void staticMethod() {
		System.out.println("FAP.staticMethod() is calling...");
	}
	 */
	public static void staticMethod() {
		System.out.println("FAP.staticMethod() is calling...");
	}
}
           

 輸出為:

super.call() is calling...

super.show() is calling...

super.call2() is calling...

super.show2() is calling...

super.print() is calling...

super.staticMethod() is calling...

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

FAP.call() is calling...

FAP.show() is calling...

super.call2() is calling...

super.show2() is calling...

super.print() is calling...

super.staticMethod() is calling...

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

FAP.call() is calling...

FAP.show() is calling...

super.call2() is calling...

super.show2() is calling...

super.print() is calling...

FAP.print(String str) is calling... message = hello world

FAP.staticMethod() is calling...

 * static方法不能被覆寫,因為方法覆寫是基于運作時動态綁定的,而static方法是編譯時靜态綁定的。

   對靜态方法的調用不存在任何動态的分派機制。 當一個程式調用了一個靜态方法時,要被調用的方法

   都是在編譯時刻被標明的, 而這種標明是基于修飾符的編譯期類型而做出的。

   子類中可以建立相同簽名static的方法,但是不會覆寫父類的static方法。

   不能建立相同簽名的非static方法,編譯器會認為試圖覆寫static方法而報錯。

 * 方法重載的選擇是在編譯時靜态綁定的,方法覆寫的選擇是在運作時根據具體類型動态綁定的。

   編譯時會根據方法調用時使用的接口或者基類的方法簽名決定調用哪一個接口方法,運作時

   再根據目前對象的具體類型,判斷接口方法在目前對象所屬類的實作中是否被覆寫過,如果覆寫了就

   調用覆寫過的版本,否則調用接口方法。

 * final方法和private方法的差別:

   類中任何private方法預設是private final的,因為你不能通路一個private方法,是以你不能覆寫它。

  (雖然當你試圖覆寫一個private方法時,編譯器沒有給出錯提示,但你并沒有覆寫這個方法,你隻是

   建立了一個新的方法而已。)

   final方法通常不會是private的,是以一般在子類或者類外部可以通路,由于其在子類中可見,是以不能

   建立相同簽名的方法。

 * private方法隻可以在類的内部使用,在類外根本通路不到,而final方法可以在類外通路,

   但是不可以重寫該方法(在子類中試圖覆寫時編譯器會給出錯誤提示,申明final方法不能被覆寫。),

   就是說可以使用該方法的功能但是不可以改變其功能,這就是private方法和final方法的最大差別。

 * final的方法可以内聯(inline)優化,private的和static的也可以進行同樣的優化。