2010-01-29 100 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

静态成员可以是静态数据成员和静态方法,可以在不使用对象的情况下进行访问。它被嵌套类使用