<strong><span style="font-size:32px;color:#3333ff;">Java多態及靜態方法對動態方法的調用</span></strong>
例子:
public class FirstJava {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
aBird a = new aBird();
bBird b = new bBird();
dosomething(a);
dosomething(b);
}
static void dosomething(Bird bird){
bird.fly();
}
}
abstract class Bird{<span style="white-space:pre"> </span>//創建一個父類
void fly() { //必須帶括號
}
}
class aBird extends Bird{<span style="white-space:pre"> </span>//子類繼承父類
void fly(){
System.out.print("i am a abird; ");
}
}
class bBird extends Bird{<span style="white-space:pre"> </span>//子類繼承父類
void fly(){
System.out.print("i am a bbird; ");
}
}
- No enclosing instance of type StaticCallDynamic is accessible. Must qualify the allocation with an enclosing instance of type StaticCallDynamic (e.g.
x.new A() where x is an instance of StaticCallDynamic).
經過查證,是因爲內部類是動態的(無static關鍵字修飾),而main方法是靜態的,普通的內部類對象隱含地保存了一個引用,指向創建它的外圍類對象,所以要在static方法(類加載時已經初始化)調用內部類的必須先創建外部類。即應該這樣創建“DanymicTest test = new StaticCallDynamic().new DanymicTest();”其中StaticCallDynamic爲外部類,DanymicTest爲內部動態類;如果將內部內修改爲靜態類,可以在main中直接創建內部類實例。
順便看了下靜態方法對動態方法的調用,如果在靜態方法中直接調用靜態方法,其中print()爲類中的動態方法,會出現如下問題:
Cannot make a static reference to the non-static method print() from the type StaticCallDynamic
這個要從java的內存機制去分析,首先當你New 一個對象的時候,並不是先在堆中爲對象開闢內存空間,而是先將類中的靜態方法(帶有static修飾的靜態函數)的代碼加載到一個叫做方法區的地方,然後再在堆內存中創建對象。所以說靜態方法會隨着類的加載而被加載。當你new一個對象時,該對象存在於對內存中,this關鍵字一般指該對象,但是如果沒有new對象,而是通過類名調用該類的靜態方法也可以。
程序最終都是在內存中執行,變量只有在內存中佔有一席之地時纔會被訪問,類的靜態成員(變態和方法)屬於類本身,在類加載的時候就會分配內存,可以通過類名直接去訪問,非靜態成員(變量和方法)屬於類的對象,所以只有在類的對象產生(創建實例)的時候纔會分配內存,然後通過類的對象去訪問。在一個類的靜態成員中去訪問非靜態成員之所以會出錯是因爲在類的非靜態成員不存在的時候靜態成員就已經存在了,訪問一個內存中不存在的東西當然會出錯。
所以要麼將方法也改爲靜態方法,要麼通過創建該方法所在的實例再通過實例來調用。
部分內容參考:Java中出現No enclosing instance of type XXX is accessible問題