2

I am trying to understand my way around polymorphism in Java. I created a parent class that has too many common methods that all children will use in the same manner.
Each of the subclasses' children all share static information, These variables or information will be used in the methods declared only in the parent.
The problem wish accessing static variables from Parent methods seems not really possible,
Its a solution to declare the common information per instance but since there will be 1000s of instances its such a waste of memory.
A simple elaboration of what i mean is the following code :

    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();
    }
 }

the output i expect was
1
2
1.
but what happens is :
1
2
2
One might think that on the initiation of each subclass the static variables of this subclass is set and then all methods referring to this subclass has access to the corresponding 'k' value.
But what actually happens is that all subclasses edit in the same static variable that is shared along all subclasses and hence destroys my whole point of using static variables for each subclass and its instances and using commmon methods in the Parent accessing these variables.



Any idea how can this be done ?

Adham
  • 490
  • 4
  • 12
  • yes since in my application each subclass will have at least 500 instance at runtime, and the common variables are String arrays, dont you think its a HUGE waste of memory not to use static ? – Adham Mar 22 '11 at 19:31

4 Answers4

5

An option is to access the subclasses' static data through an abstract (non-static) method:

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; }
}
Michael Brewer-Davis
  • 14,018
  • 5
  • 37
  • 49
2

When you make new testChild2().print(); the static block on testChield2 was executed and change the value to 2.

static blocks only execute once when loaded by the ClassLoader.

This one give the output you want:

 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();
    }
 }

Non static code blocks execute everytime the class is instanciated.

Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167
  • 2
    Sure, this _works_, but you're still changing the value of a single static variable. The right solution here is to use instance variables, not static ones. – Matt Ball Mar 22 '11 at 16:48
  • Yes. You need to shadowing of the variables, but they are evil too. Try to rethink of design if you have such scenarios. Please look at this link on issues with Shadowing. http://www.roseindia.net/java/java-tips/data/variables/60shadow-variables.shtml – Phani Mar 22 '11 at 16:51
  • yes in this specific examples this will work, but in a scenario where i have already created Objects of class A and i create a new object of class B calling a method in class A's instance gets us back to this. – Adham Mar 22 '11 at 19:36
1

Static variables are specific to the class itself. If you want the same field in different instances of a class to have different values, then that field cannot be static.

The solution: don't make k static.

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
(ignore the static class business - that's just to make it work in ideone).

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • yes but in my application each subclass will have at least 500 instance at runtime, and the common variables are String arrays, dont you think its a HUGE waste of memory not to use static ? – Adham Mar 22 '11 at 19:32
  • I think you're missing the point. Unless each instance's string array is **identical** to the other instances' string arrays, static is **not the answer**. There are other memory-saving tricks, like [string interning](http://en.wikipedia.org/wiki/String_interning). – Matt Ball Mar 22 '11 at 19:36
  • im not sure if i was not clear enough, but in each Subclass all instances share the IDENTICAL string array. – Adham Mar 22 '11 at 19:40
  • That was not clear at all! Your question asks about using different values in each instance of the subclass. – Matt Ball Mar 22 '11 at 20:02
1

Premature optimization is the root of all evil. I don't think you'll run into any memory issues with thousands of instances, each with their own data, unless you're working on a tiny embedded system of some kind. Static variables are not intended to do what you're trying to do with them.

Shaun
  • 2,446
  • 19
  • 33
  • We don't know what the real data is (ints? images?), so thousands may be an obvious memory problem for OP, or it may be a premature optimization. – Michael Brewer-Davis Mar 22 '11 at 16:58
  • Well to be honest there will be at least 5 different subclasses, each sub class will have at least 200 instance and the data is Array of string, i think it will be a performance hindering. – Adham Mar 22 '11 at 19:33