2010-01-29 101 views
0

我讀過Java中的Statics不會被繼承。我有一個小程序,在運行時編譯並生成2 2作爲輸出。從程序看來,k(一個靜態變量)正在被繼承!我究竟做錯了什麼?Java中的靜態成員

class Super 
{ 
    int i =1; 
    static int k = 2; 
    public static void print() 
    { 
     System.out.println(k); 
    } 
} 
class Sub extends Super 
{ 
    public void show() 
    { 
     // I was expecting compile error here. But it works !! 
     System.out.println(" k : " + k); 
    } 
    public static void main(String []args) 
    { 
     Sub m =new Sub(); 
     m.show(); 
     print(); 
    } 
} 
+0

從來沒有聽說過,你的假設可能是錯誤的。 – 2010-01-29 09:42:00

+0

我在這裏閱讀:http://stackoverflow.com/questions/1740528/inheritance-vs-static-in-java – gameover 2010-01-29 09:43:24

+1

如果你閱讀了關於這個的評論,那麼這張海報正在將'繼承'表示爲'繼承的能力用多態運行時調度來覆蓋「,這有點不合常規,容易混淆。 – 2010-01-29 09:49:15

回答

3

查找姓名的範圍包含超類。

Sub中找不到名稱print,因此在Super中解決。

當編譯器生成字節碼時,將調用Super.print,而不是調用Sub中的方法。

同樣的k是在子類中可見,且不限定它。


這裏沒有多態性,只有名稱空間內容的繼承。靜態方法和所有字段在Java中都沒有多態調度,所以只能被子類隱藏,而不能被覆蓋。你在評論中鏈接的文章是以一種非常規的方式使用「繼承」,並將其與多態性混合在一起。沒有多態性,你可以擁有沒有繼承和繼承的多態。

+0

「可見」和「繼承」不一樣嗎? – gameover 2010-01-29 09:54:58

+1

如果A類有一個公共方法「doSomething()」,那麼B類可以訪問A.doSomething()。這意味着A.doSomething()對於B來說是「可用的」。但是,你真的認爲B有「繼承」A.doSomething()嗎? ;-) – 2010-01-29 12:31:29

+1

如果B擴展A,是的,你描述的是繼承。如果B不擴展A,那麼你描述的就是使用。您可以使用您委派的對象來模擬繼承;早期的VB COM確實如此 - 它具有多態性,但不具有繼承性。 – 2010-01-30 10:40:17

0

Sub extends Super,因此它可以看到Super的所有public/protected/package(靜態)成員。

我想這是你所描述的「在Java中靜不繼承」 變化

static int k = 2; 

private static int k = 2; 

和你的子程序將不會看到「K」再和不會編譯;

也嘗試創建一個新的'靜態int k = 3;'在Sub中,看看會發生什麼。

-1

我想你可能是錯誤的靜態變量不被繼承。我想它的一些屬性不會被繼承。例如,靜態變量通常意味着類的所有實例都可以訪問內存中的相同位置。

當您繼承時,派生類不會引用與基類相同的內存。

+0

最後一句是錯誤的。如果只在基類中定義靜態變量,則內存中只有一個變量實例。所有對該靜態成員的引用(來自基類或派生類)都將修改單個實例。 – 2010-01-29 10:17:53

0

這與訪問Math.PI或任何其他全局常量(也有publicfinal修飾符)幾乎相同。

在你的情況下你有默認的(包)範圍。

它是獨立的繼承只有範圍限制它是否可見。

0

在Java中,靜態方法不能被覆蓋,此外,構造函數(這是一種特殊的靜態方法)不被繼承。

+0

構造函數 - 特殊的靜態方法?? ! – 2010-01-29 12:33:27

+1

如果您使用新的XYZ()調用構造函數,這不是發送給實例但發送給類的消息。 – bertolami 2010-01-29 14:01:38

+0

如果構造函數是靜態的,爲什麼* this *關鍵字可用? – vikingsteve 2013-08-08 11:08:21

0

靜態成員可以是靜態數據成員和靜態方法,可以在不使用對象的情況下進行訪問。它被嵌套類使用