這是一個匿名的內部類。它創建一個對象,該對象是某個類的子類TestClass的實例,您不希望爲該子類提供一個名稱(因爲您只需要即時創建對象,並且無需在任何地方使用該類其他)。
代碼只初始化對象,實際上並沒有調用正在創建的對象的方法,所以這就是爲什麼你沒有看到任何輸出。你可以添加一行代碼
public static void main (String[] args) throws java.lang.Exception
{
TestClass TC = new TestClass() {
public void testprint() {
System.out.println("Z is " + getZ());
}
};
// <- call the new method (>_< this won't compile)
TC.testprint();
}
除了這一點,因爲testprint沒有定義爲TestClass的方法是行不通的,局部變量引用對象的類型爲TestClass中,所以編譯器能夠找到在TestClass或TestClass的超類上定義的方法。你可以某種方法添加到TestClass中,像這樣:
abstract class TestClass {
int z;
public TestClass(){
z=10;
}
public int getZ(){
return z;
}
public void setZ(int z){
this.z=z;
}
// add new method
public abstract void testprint();
}
現在編譯器知道期待那種類型的TestClass的對象將有一個名爲testprint方法。我不必製作TestClass抽象,我可以添加一個testprint的測試。但是,由於TestClass是抽象的,很明顯新對象不是TestClass,而是它的一些子類。
或者,也可以通過TestClass的另一個已公開的方法調用此方法。用你的TestClass不變,但改變的主要方法:
public static void main (String[] args) throws java.lang.Exception
{
TestClass TC = new TestClass() {
public void testprint() {
System.out.println("Z is " + super.getZ());
}
// override Z getter to call testprint
@Override public int getZ(){
testprint();
return z;
}
};
TC.getZ(); // <- call method on object created above
}
testprint不得不改變調用父類的版本的Z的獲取的,所以我們不會有一個無限遞歸。現在的匿名子類在Z吸氣調用testprint方法,這樣你就可以調用getter和看到輸出:
Z is 10
的代碼不分配子類的名稱,但它仍然得到一個分配給它。如果我添加一行的主到底看到了什麼匿名類內部調用:
System.out.println(TC.getClass());
它打印
class A$1
在實踐中不能夠直接調用新的方法中定義的一個匿名類不是一個限制。如果要將類的實現傳遞給某個其他對象的方法,則需要提供一個匿名類,該方法需要匿名類的對象不知道(也不應該知道,請參閱LSP)如何無論如何要調用新方法。
問題是,如果testprint()不是TestClass的一個方法,但只在匿名類( - >不覆蓋方法)中定義,則不能像這樣調用它... – Puce
作爲一種替代方法,如果基類沒有定義它,那麼您可以從匿名類的另一個方法或初始化程序中調用該方法。 – Puce
@Puce:謝謝,很好的建議。 –