官方辦法
JAVA語言提供的一個關鍵字“FINAL”可以用來履行該任務。看看下面的源代碼范例:
//FinalDemo.java
public final class FinalDemo {
}
下面讓我們來制作另一個類,它將會繼承上面聲明的類。JAVA語言提供的“EXTENDS”關鍵字將能夠使得一個類繼承于一個現有的類。
//FinalDemo2.java
public class FinalDemo2 extends FinalDemo {
}
在編譯第一個類后,如果你接著編譯第二個類,那么JDK編譯器報錯,你會得到下列錯誤信息:
FinalDemo2.java:1: cannot inherit from final FinalDemo
public class FinalDemo2 extends FinalDemo{}
^
1 error
現在,你已經通過官方辦法來成功阻止了第一個類被另一個類所繼承。
非官方辦法
但是,阻止類被其他類所繼承的辦法也不是唯一的。考慮下面的代碼,我聲明了構造方法為私有(private)的, 而且也聲明了一個靜態方法(static method)來返回一個類對象。
public class PrivateTest{
private PrivateTest(){
System.out.println("Private Default Constructor");
}
public static PrivateTest getInstance(){
return new PrivateTest();
}
}
上面被修改的代碼被稱為是"Singleton模式," 一個getInstance方法總是只返回這個類的一個實例。 但是為什么這段代碼阻止了類被繼承呢?考慮下面的代碼,聲明的類應該能繼承上面的類。
public class PrivateTest2 extends PrivateTest{
}
在編譯第一個類后,如果你接著編譯第二個類,那么JDK編譯器報錯,你會得到下列錯誤信息:
PrivateTest2.java:1: PrivateTest() has private access in PrivateTest
public class PrivateTest2 extends PrivateTest{
^
1 error
第二個類不能繼承第一個類。 但是提示錯誤的意思是什么呢? JAVA語言要求在一個類中至少要提供一個構件方法。 如果你沒有提供任何構件方法, JDK將會在你聲明的類中插入一個默認的構件方法。 換句話說,默認的是一個不帶參數,空構件體,和一個公共(public)訪問權限的構件方法。 但是,如果你自己定義了一個構件方法, 那么JDK編譯器就不會插入這么默認的構件方法。我們剛才在PrivateTest類中聲明了一個默認的構件方法,但是我們將默認的public訪問權限改為了private權限,這些都是符合JDK編譯器語法檢查的規則的。
現在我們來看看第二個部門。JAVA語言也要求你必須在構件方法里的第一行來調用(call)超類(super class)的構件方法。 這個是啟動繼承特征所必須的。 在JAVA中,我們通過調用super()這個方法來完成這個任務,它將會映射到一個超類的構件方法中。 如果你沒有給超類提供一個默認的構造方法,那么JDK編譯器將會插入一個默認的超類構件方法用來調用。
我們剛才在第一個類中將構造器聲明為private的權限。現在,當我們在其他類中繼承這個類的時候,編譯器將會嘗試調用一個默認的超類構件方法。因為超類范圍內的構件方法是聲明為private權限的, 編譯器將報錯,說不能調用超類構件方法。因此,我們通過非官方辦法阻止了一個類被其他類所繼承。
Usman Saleem
Mohammad Ali Jinnah University
E-mail: [email protected]