This site requires JavaScript, please enable it in your browser!
Greenfoot back
Zamoht
Zamoht wrote ...

2013/10/16

Subclasses and statics

1
2
Zamoht Zamoht

2013/10/16

#
public class ClassA
{
    private static final int value = 10;
    int v;
    
    public ClassA()
    {
        v = value;
    }
}
public class ClassB extends ClassA
{
    private static final int value = 20; 
    
    public ClassB()
    {
        super();
    }
}
If a new object of ClassB is created using the code above the object's v will be 10. What I want it to be is 20 or what ever the static in ClassB is set to. I have found one way of fixing this:
public class ClassB extends ClassA
{
    private static final int value = 20; 
    
    public ClassB()
    {
        super();
        v = value;
    }
}
But with more subclasses and values this becomes messy I think. I would like to know if there is an easier/cleaner way if doing what I want. What I really want is that all the code is in the superclass so all I have to do in the subclasses is changing the static value. EDIT: I think I found that using protected instead of private fixes it.
danpost danpost

2013/10/16

#
Have you tried passing the static value from the class being instantiated to ClassA in the 'super' call:
super(value);
ClassA would then need two constructors:
public ClassA()
{
    this(value);
}

public ClassA(int val)
{
    v = val;
}
Zamoht Zamoht

2013/10/16

#
I guess that could work as well. Though as I stated in the EDIT I found that changing private to protected fixes the problem and makes the program do exactly what I wanted. Thanks for your time and answer anyway.
davmac davmac

2013/10/16

#
I think I found that using protected instead of private fixes it.
I don't think that's possible. A simple experiment shows that this is not the case. Probably the best way to achieve what you want is to have the ClassA constructor take a parameter which specifies the desired value for B. Then for ClassB you could have:
    public class ClassB extends ClassA  
    {  
        private static final int value = 20;   
          
        public ClassB()  
        {  
            super(value);  
            v = value;  
        }  
    }
Zamoht Zamoht

2013/10/16

#
Oh my bad... I failed badly :( Thought I deleted the v = value from my code, but I didn't.
danpost danpost

2013/10/16

#
Zamoht wrote...
I found that changing private to protected fixes the problem and makes the program do exactly what I wanted.
That did not seem possible, so I tested it and found that it does not work. What I suggested is probably the way to go.
davmac davmac

2013/10/16

#
I just realise that danpost has suggested the same solution as me (though earlier); somehow I missed this when reading the thread. I do believe his suggestion is the correct way to solve this problem.
Zamoht Zamoht

2013/10/16

#
Okay one last thing then. What if I want to get the value?
public class ClassA extends Actor
{
    protected static final int value = 10;
    
    public int getValue()
    {
        return value;
    }
}
public class ClassB extends ClassA
{
    protected static final int value = 20;
}
This will return 10 for both ClassA and ClassB. So to get 20 from ClassB I can add the get method to that class.
public class ClassB extends ClassA
{
    protected static final int value = 20; 
    
    public int getValue()
    {
        return value;
    }
}
I know it's only like two lines of code, but it just seems odd that I have to add the method to every single subclass. I bet this is the only way to do what I want, but I just want to make sure.
danpost danpost

2013/10/16

#
I believe you are trying to return the incorrect field. Return 'v', not 'value'.
Zamoht Zamoht

2013/10/16

#
No no this is a new example where I just want to return the static 'value'.
danpost danpost

2013/10/16

#
If you made the static values 'public' you could get the value of any of the classes by 'ClassA.value', 'ClassB.value', etc. or by using an object of that class (but I am not sure if it needs to be typecast to that class -- in other words, if you create a ClassB object and you have it cast as a ClassA object, I would guess it would not return the correct value).
ClassA aObj = new ClassB();
System.out.println(""+aObj.value);
ClassB bObj = (ClassB) aObj;
System.out.println(""+bObj.value);
I believe, even though it is the same object, this would output: 10 20
davmac davmac

2013/10/16

#
I know it's only like two lines of code, but it just seems odd that I have to add the method to every single subclass. I bet this is the only way to do what I want, but I just want to make sure.
It doesn't seem odd to me. A static method belongs to a class and has no dynamic behavior. The method getValue() in ClassA returns the value of the "value" variable in ClassA. You seem to be expecting that if another class - ClassB - inherits the getValue() method it will actually inherit a modified version which returns the value of the "value" variable from ClassB (which is actually a completely separate variable which just happens to have the same name). That's just not what happens. Putting it another way, when you define "protected static final int value = 20;" in ClassB you aren't actually overriding the same variable in ClassA. You are shadowing it because you used the same name, but the variables ClassA.value and ClassB.value are two separate variables.
Zamoht Zamoht

2013/10/16

#
The thing is that I store/keep reference to the superclass. So I keep a reference to any subclass as lets say ClassA it could be ClassB, ClassC or even ClassD it doesn't matter. The thing is that when I call getValue() it should return a different value depending on the "real" class. ClassA myObject = new ClassB; System.out.println(myObject.getValue()); myObject = new ClassC; System.out.println(myObject.getValue()); this should print out two different values depending on the defined static final int value in that class.
danpost danpost

2013/10/16

#
Why are these fields 'static'? What reason do you have for making them so?
Zamoht Zamoht

2013/10/16

#
Okay I get it I just wanted to know if there was an other way to go around it.
There are more replies on the next page.
1
2