Shadow Variables and Inheritance

B

bfeist

I want to have a static constant X defined in a superclass A and given
various different values in subclasses B, C, and so on. When the X is
accessed in a method of A by class B (through inheritance), I want it
to get the value of B.X, not A.X. Is this possible?

My initial naive attempt at just defining X separately in each class as
a static final did not work; A.X is accessed instead. Unless someone
has a better idea, I'll resort to replacing the constant by a static
method returning the desired constant instead, and rely on
polymorphism.

Any ideas? Thanks in advance.
 
O

Oliver Wong

I want to have a static constant X defined in a superclass A and given
various different values in subclasses B, C, and so on.

Right here, there's a conceptual problem. Since X is static, there is
only "one of" it. There isn't one for A, another for B, another for C, and
so on. There's just one. And it can take on exactly one value at any point
in time. And in this case, because it's constant, it has to take the same
value for the entire program run.
When the X is
accessed in a method of A by class B (through inheritance), I want it
to get the value of B.X, not A.X. Is this possible?

You would have to declare a different static constant named X in B.
My initial naive attempt at just defining X separately in each class as
a static final did not work; A.X is accessed instead.

If you had typed in A.X, then A.X will get access. If you had instead
typed B.X, B.X would get accessed.
Unless someone
has a better idea, I'll resort to replacing the constant by a static
method returning the desired constant instead, and rely on
polymorphism.

You might have better luck using a non-static method.

- Oliver
 
M

Mike Schilling

I want to have a static constant X defined in a superclass A and given
various different values in subclasses B, C, and so on. When the X is
accessed in a method of A by class B (through inheritance), I want it
to get the value of B.X, not A.X. Is this possible?

My initial naive attempt at just defining X separately in each class as
a static final did not work; A.X is accessed instead. Unless someone
has a better idea, I'll resort to replacing the constant by a static
method returning the desired constant instead, and rely on
polymorphism.

Any ideas? Thanks in advance.

There is a way to do this, but it's so hideous that I won't explain it, lest
someone actually do it.

If you want polymorphic behavior, use an instance method. If you need the
value to be a constant (because it's used in, say, a case label), you can
have your instance method return the value of the constant,e .g.

class A {
public static void int THE_ANSWER = 42;

public int getMagicNumber {
return THE_ANSWER ;
}
}

class B extends A {
public static void int THE_QUESTION = 41;

public int getMagicNumber {
return THE_QUESTION ;
}
}
 
O

Oliver Wong

Mike Schilling said:
class A {
public static void int THE_ANSWER = 42;

public int getMagicNumber {
return THE_ANSWER ;
}
}

class B extends A {

The question should be:

public static void int THE_QUESTION = 6 * 9;
public int getMagicNumber {
return THE_QUESTION ;
}
}

And both the question and the answer should be declared final.

- Oliver
 
B

bfeist

Oliver said:
Right here, there's a conceptual problem. Since X is static, there is
only "one of" it. There isn't one for A, another for B, another for C, and
so on.
You would have to declare a different static constant named X in B.

That's what I meant by a shadow variable -- the same name, but declared
and given values in two different classes.
If you had typed in A.X, then A.X will get access. If you had instead
typed B.X, B.X would get accessed.

Alas! That's exactly what happened.
You might have better luck using a non-static method.

What will happen if I use static? Something analagous to my
experiences with static constants, where there's no dynamic binding
based on the run-time class involved?

Thanks,

Bruce Feist
 
B

bfeist

There is a way to do this, but it's so hideous that I won't explain it, lest
someone actually do it.

Sir, please don't arouse my curiousity like that unless you plan to
satisfy it! I don't care how hideous it is, I must know!

Thanks,
Bruce
 
M

Mike Schilling

Oliver Wong said:
The question should be:

public static void int THE_QUESTION = 6 * 9;

Better still:

public static void int THE_QUESTION = 42; /* 6 * 9 */
And both the question and the answer should be declared final.

(Regis Philbin voice) Is that your final answer?
 
M

Mike Schilling

bfeist said:
Sir, please don't arouse my curiousity like that unless you plan to
satisfy it! I don't care how hideous it is, I must know!

Use reflection.
 
O

Oliver Wong

bfeist said:
What will happen if I use static? Something analagous to my
experiences with static constants, where there's no dynamic binding
based on the run-time class involved?

Right. The rule of thumb is that things which are static don't get
inherited, and so any rules about inheritance (and thus dynamic binding)
doesn't apply.

- Oliver
 
O

Oliver Wong

Mike Schilling said:
Use reflection.

Beware, though. There is a theory which states that if ever anyone
discovers how to emulate the inheritance of static members via reflection,
the Java language as we know it will instantly disappear and be replaced by
something more bizarrely inexplicable.

There is another theory which states this has already happened
(somewhere between 1.4 and 1.5).

- Oliver
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top