final
1)用final修飾的類不能被繼承,沒有子類;用final修飾的方法不能被子類的方法覆蓋;用final修飾的變量表示常量,只能被賦一次值。
final不能用來修飾構造方法,父類中用private修飾的方法不能被子類的方法覆蓋。final方法是不允許子類方法中寫一個同樣簽名的方法的,但private的情況下,你可以定義一個同樣簽名的方法。(final方法不能重載,private方法可以重載)
class FinalExtends {
private void goDown() {
System.out.println("hello A");
}
}
class FinalTest extends FinalExtends {
public void goDown() {
System.out.println("hello B");
}
public static void main(String[] args) {
FinalTest xx = new FinalTest();
xx.goDown();
}
}
結果爲:
hello B
2)final類
final類不能被繼承,因此final類的成員方法沒有機會被覆蓋,默認都是final 的。在設計類時候,如果這個類不需要有子類,類的實現細節不允許改變,並且確信這個類不會載被擴展,那麼就設計爲final類。
3) final方法
如果一個類不允許其子類覆蓋某個方法,則可以把這個方法聲明爲final方法。 使用final方法的原因有二:
第一、把方法鎖定,防止任何繼承類修改它的意義和實現。
第二、高效。編譯器在遇到調用final方法時候會轉入內嵌機制,大大提高執行效率。
class Test2 {
public void f1() {
System.out.println("f1");
}
// 無法被子類覆蓋的方法
public final void f2() {
System.out.println("f2");
}
public void f3() {
System.out.println("f3");
}
private void f4() {
System.out.println("f4");
}
}
public class Test1 extends Test2 {
public void f1() {
System.out.println("Test2父類方法f1被覆蓋!");
}
public static void main(String[] args) {
Test1 t = new Test1();
t.f1();
t.f2(); // 調用從父類繼承過來的final方法
t.f3(); // 調用從父類繼承過來的方法
//t.f4(); //調用失敗,無法從父類繼承獲得
}
}
結果爲:
Test2父類方法f1被覆蓋!
f2
f3
4)final變量(常量)
用final修飾的成員變量表示常量,值一旦給定就無法改變!
final修飾的變量有三種:靜態變量、實例變量和局部變量,分別表示三種類型的常量。
從下面的例子中可以看出,一旦給final變量初值後,值就不能再改變了。
另外,final變量定義的時候,可以先聲明,而不給初值,這中變量也稱爲final空白,無論什麼情況,編譯器都確保空白final在使用之前必須被初始化。但是,final空白在final關鍵字final的使用上提供了更大的靈活性,爲此,一個類中的final數據成員就可以實現依對象而有所不同,卻有保持其恆定不變的特徵。
對於final類型的實例變量,可以在定義變量時,或者在構造方法中進行初始化;對於final類型的靜態變量,可以在定義變量時進行初始化,或者在靜態代碼塊中初始化。
public class Sample {
static final int a = 10;
static final int b;
static {//靜態塊中初始化final類型靜態成員變量
b = 15;
}
void methodPrintln() {
System.out.println("調用方法輸出:");
System.out.println(a);
System.out.println(b);
}
public static void main(String[] args) {
Sample sa = new Sample();
System.out.println("實例化對象輸入");
System.out.println(sa.a);
System.out.println(sa.b);
System.out.println("靜態成員變量,不用實例化也可以輸出:");
System.out.println(Sample.a);
System.out.println(Sample.b);
sa.methodPrintln();
}
}
結果爲:
實例化對象輸入
10
15
靜態成員變量,不用實例化也可以輸出:
10
15
調用方法輸出:
10
15
如果將引用類型的變量用final修飾,那麼該變量只能始終引用一個對象,但可以改變對象的內容。
public class FinalSample {
public int var;
public FinalSample(int var) {
this.var = var;
}
public static void main(String[] args) {
final FinalSample s = new FinalSample(1);
s.var = 2;
System.out.println(s.var);
// 出錯,不能改變引用變量s所引用的FinalSample類的對象
// s=new FinalSample(2);
}
}
5)final參數
當函數參數爲final類型時,你可以讀取使用該參數,但是無法改變該參數的值。
class Test4 {
public static void main(String[] args) {
new Test4().f1(2);
}
public void f1(final int i) {
// i++; //i是final類型的,值不允許改變的.
System.out.print(i);
}
}