views:

3032

answers:

5

Hi,

class Dad
{
 protected static String me = "dad";

 public void printMe()
 {
  System.out.println(me);
 }
}

class Son extends Dad
{
 protected static String me = "son";
}

public void doIt()
{
 new Son().printMe();
}

The function doIt will print "dad". Is there a way to make it print "son"?

Thanks!

Dikla

+5  A: 

Yes, just override the printMe() method:

class Son {
        public static final String me = "son";

        @Override
        public void printMe() {
                System.out.println(me);
        }
}
romaintaz
+1  A: 

only by overriding printMe():

class Son extends Dad 
{
    public void printMe() 
    {
        System.out.println("son");
    }
}

the reference to me in the Dad.printMe method implicitly points to the static field Dad.me, so one way or another you're changing what printMe does in Son...

Dan Vinton
+4  A: 

This looks like a design flaw.

Remove the static keyword and set the variable for example in the constructor. This way Son just sets the variable to a different value in his constructor.

Patrick Cornelissen
whats incorrect about this? If the 'me' member variable is supposed to be overridable in your design, then patrick's is the correct solution
Chii
Actually, if the value of me is the same for every instance, just removing 'static' would be fine. Initialization doesn't have to be in constructor.
drhorrible
Right, although technically (in bytecode) I think it's almost the same ;-)
Patrick Cornelissen
+1  A: 

You cannot override variables in a class. You can override only methods. You should keep the variables private otherwise you can get a lot of problems.

Ionel Bratianu
You can't override any statics.
Tom Hawtin - tackline
(or at least it doesn't make sense, IFSWIM.)
Tom Hawtin - tackline
+2  A: 

In short, no, there is no way to override a class variable.

You do not override class variables in Java you hide them. Overriding is for instance methods. Hiding is different from overriding.

In the example you've given, by declaring the class variable with the name 'me' in class Son you hide the class variable it would have inherited from its superclass Dad with the same name 'me'. Hiding a variable in this way does not affect the value of the class variable 'me' in the superclass Dad.

For the second part of your question, of how to make it print "son", I'd set the value via the constructor. Although the code below departs from your original question quite a lot, I would write it something like this;

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public void printName() {
        System.out.println(name);
    }
}

The JLS gives a lot more detail on hiding here;

http://java.sun.com/docs/books/jls/second%5Fedition/html/classes.doc.html

Mike