2011-03-22 140 views
2

我想了解我在Java中使用多态的方法。我创建了一个拥有太多通用方法的父类,所有孩子都会以相同的方式使用。
每个子类的子元素都共享静态信息,这些变量或信息将用于仅在父类中声明的方法中。
问题希望从父方法访问静态变量似乎不是真的可能,
它是一种解决方案来声明每个实例的公用信息,但因为将有1000个实例它的这样的浪费内存。
的我的意思是将以下代码的简单阐述:Java:父类访问子类的静态变量的方法?

class testParent { 
    static int k; 
    public void print() 
    { 
     System.out.println(k);  
    } 
    } 

    class testChild2 extends testParent 
    { 

    static 
    { 
     testChild2.k =2; 
    } 
    } 

    public class testChild1 extends testParent{ 
    static 
    { 
     testChild1.k = 1; 
    } 

    public static void main(String[] args) 
    { 

     new testChild1().print(); 
     new testChild2().print(); 

     new testChild1().print(); 
    } 
} 

i的输出想到的是
1.
但发生的事情是:
有人可能会认为,在启动每个子类时这个子类的静态变量被设置,然后引用这个子类的所有方法都可以访问相应的'k'值。
但实际情况是,所有子类都编辑在所有子类共享的相同静态变量中,因此破坏了我为每个子类及其实例使用静态变量的整个观点,并在访问这些变量的Parent中使用commmon方法。



任何想法如何做到这一点?

+4

是否ķ必须是静态的? – Belinda 2011-03-22 16:43:00

+0

是的,因为在我的应用程序中,每个子类在运行时将至少有500个实例,并且公共变量是字符串数组,你不觉得它浪费大量内存而不使用静态吗? – Adham 2011-03-22 19:31:01

回答

4

一个选择是通过一个抽象访问子类静态数据(非静态)方法:

abstract public class Parent { 
    protected abstract int getK(); 

    public void print() { 
     System.out.println(getK()); 
    } 
} 

public class Child1 extends Parent { 
    private static final int CHILD1_K = 1; 

    protected int getK() { return CHILD1_K; } 
} 

public class Child2 extends Parent { 
    private static final int CHILD2_K = 2; 

    protected int getK() { return CHILD2_K; } 
} 
1

当你做出新的testChild2()。print();执行testChield2上的静态块并将其值更改为2.

静态块仅在由ClassLoader加载时执行一次。

这一个给你想要的输出:

class testParent { 
    static int k; 
    public void print() 
    { 
     System.out.println(k);  
    } 
    } 

    class testChild2 extends testParent 
    { 

    { 
     testChild2.k =2; 
    } 
    } 

    public class testChild1 extends testParent{ 
    { 
     testChild1.k = 1; 
    } 

    public static void main(String[] args) 
    { 

     new testChild1().print(); 
     new testChild2().print(); 

     new testChild1().print(); 
    } 
} 

非静态代码块每次执行的类实例化。

+2

当然,这个_works_,但你仍然在改变一个静态变量的值。这里的正确解决方案是使用实例变量,而不是静态变量。 – 2011-03-22 16:48:01

+0

是的。你需要隐藏变量,但它们也是邪恶的。如果您有这种情况,请尝试重新考虑设计。请看这个关于Shadowing问题的链接。 http://www.roseindia.net/java/java-tips/data/variables/60shadow-variables.shtml – Phani 2011-03-22 16:51:07

+0

是在这个具体的例子中,这将工作,但在一个场景中,我已经创建了类A和我创建了一个类B的新对象,调用A类的实例中的一个方法,让我们回到这个。 – Adham 2011-03-22 19:36:31

1

静态变量是特定于类本身的。如果您希望类的不同实例中的相同字段具有不同的值,那么该字段不能是静态的。

解决方案:不要让k静态。

class testParent { 
    int k; 
    public void print() 
    { 
     System.out.println(k);  
    } 
} 

class testChild2 extends testParent 
{ 
    { 
     this.k =2; 
    } 
} 

class testChild1 extends testParent{ 
    { 
     this.k = 1; 
    } 

    public static void main(String[] args){ 
     new testChild1().print(); 
     new testChild2().print(); 
     new testChild1().print(); 
    } 
} 

Demo
(忽略static class业务 - 这只是使它在ideone工作)。

+0

是的,但在我的应用程序中,每个子类在运行时将至少有500个实例,并且公共变量是字符串数组,您是否认为它浪费内存不使用静态? – Adham 2011-03-22 19:32:19

+0

我认为你错过了这一点。除非每个实例的字符串数组与**其他实例的字符串数组** ** **相同​​,否则静态**不是答案**。还有其他节省内存的技巧,如[字符串实习](http://en.wikipedia.org/wiki/String_interning)。 – 2011-03-22 19:36:30

+0

im不知道如果我不够清楚,但在每个子类中所有实例共享IDENTICAL字符串数组。 – Adham 2011-03-22 19:40:38

1

不成熟的优化是万恶之源。我不认为你会遇到数千个实例的内存问题,每个实例都有自己的数据,除非你正在研究一个小的嵌入式系统。静态变量不打算做你想要做的事情。

+0

我们不知道真实数据是什么(ints?图像?),所以数千个可能是OP的一个明显的内存问题,或者它可能是一个过早的优化。 – 2011-03-22 16:58:29

+0

说实话,至少会有5个不同的子类,每个子类至少有200个实例,数据是字符串数组,我认为这会成为阻碍性能。 – Adham 2011-03-22 19:33:53