Organizational Research By

Surprising Reserch Topic

is there a way to override class variables in java


is there a way to override class variables in java  using -'java,inheritance,override'

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"?
    

asked Sep 10, 2015 by BusIOSA
0 votes
16 views



Related Hot Questions

13 Answers

0 votes

Yes. You can override. just don't declare the variable but initialize in the constructor or static block.

The value will get reflected when using in the blocks of parent class

answered Sep 10, 2015 by IgougeAlbers
0 votes

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 in section 8.3 - Field Declarations

answered Sep 10, 2015 by DelLanger
0 votes

Yes, just override the printMe() method:

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

        @Override
        public void printMe() {
                System.out.println(me);
        }
}
answered Sep 10, 2015 by suyesh.lokhande
0 votes

You can create a getter and then override that getter. It's particularly useful if the variable you are overriding is a sub-class of itself. Imagine your super class has an Object member but in your sub-class this is now more defined to be an Integer.

class Dad
{
        private static final String me = "dad";

        protected String getMe() {
            return me;
        }

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

class Son extends Dad
{
        private static final String me = "son";

        @Override
        protected String getMe() {
            return me;
        }
}

public void doIt()
{
        new Son().printMe(); //Prints "son"
}
answered Sep 10, 2015 by SerenaBermud
0 votes

I always code for flexibility, because one day, he may have a daughter, or find a wife. My motto is, if you are going to override it don't provide a concrete implementation for it, always use abstractions. This example will show you why. Here is a flexible way to design this:

     public interface Person {
        public abstract String getName();
       //this will be different for each person, so no need to make it concrete
        public abstract void setName(String name);
    }

Now we can add the Dad:

public class Dad implements Person {

    private String name;

    public Dad(String name) {
        setName(name);
    }

    @Override
    public final String getName() {
    return name;
    }

    @Override
    public final void setName(String name) {
        this.name = name;
    }
}

the son:

public class Son implements Person {

    private String name;

    public Son(String name) {
        setName(name);
    }

    @Override
    public final String getName() {
        return name;
    }

    @Override
    public final void setName(String name) {
        this.name = name;
    }
}

and Dad met a nice lady:

public class StepMom implements Person {

    private String name;

    public StepMom(String name) {
        setName(name);
    }

    @Override
    public final String getName() {
        return name;
    }

    @Override
    public final void setName(String name) {
        this.name = name;
    }
}

Looks like we have a family, lets tell the world their names:

public class ConsoleGUI {

    public static void main(String[] args) {
        List family = new ArrayList();
        family.add(new Son("Tommy"));
        family.add(new StepMom("Nancy"));
        family.add(new Dad("Dad"));
        for (Person person : family) {
            //using the getName vs printName lets the caller, in this case the
            //ConsoleGUI determine versus being forced to output through the console. 
            System.out.print(person.getName() + " ");
            System.err.print(person.getName() + " ");
            JOptionPane.showMessageDialog(null, person.getName());
    }
}

}

System.out Output : Tommy Nancy Dad
System.err is the same as above(just has red font)
JOption Output:
Tommy then
Nancy then
Dad

answered Sep 10, 2015 by sourabh
0 votes

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.

answered Sep 10, 2015 by NannieLillic
0 votes

Though it is true that class variables may only be hidden in subclasses, and not overridden, it is still possible to do what you want without overriding printMe () in subclasses, and reflection is your friend. In the code below I omit exception handling for clarity. Please note that declaring me as protected does not seem to have much sense in this context, as it is going to be hidden in subclasses...

class Dad
  {
    static String me = "dad";

    public void printMe ()
      {
        java.lang.reflect.Field field = this.getClass ().getDeclaredField ("me");
        System.out.println (field.get (null));
      }
  }
answered Sep 10, 2015 by PasqualeCyr
0 votes

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...

answered Sep 10, 2015 by RamonJZFsdrw
0 votes
class Dad
{
    protected static String me = "dad";

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

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

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

... will print "son".

answered Sep 10, 2015 by KarMarrufo
0 votes

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.

answered Sep 10, 2015 by SamTaverner
0 votes

Of course using private attributes, and getters and setters would be the recommended thing to do, but I tested the following, and it works... See the comment in the code

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

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

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

    /* 
    Adding Method printMe() to this class, outputs son 
    even though Attribute me from class Dad can apparently not be overridden
    */

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

class Tester
{
    public static void main(String[] arg)
    {
        new Son().printMe();
    }
}

Sooo ... did I just redefine the rules of inheritance or did I put Oracle into a tricky situation ? To me, protected static String me is clearly overridden, as you can see when you execute this program. Also, it does not make any sense to me why attributes should not be overridable.

answered Sep 10, 2015 by NilBurdine
0 votes

It indeed prints 'dad', since the field is not overridden but hidden. There are three approaches to make it print 'son':

Approach 1: override printMe

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

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

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

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

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

Approach 2: don't hide the field and initialize it in the constructor

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

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

class Son extends Dad
{
    public Son()
    {
        me = "son";
    }
}

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

Approach 3: use the static value to initialize a field in the constructor

class Dad
{
    private static String meInit = "Dad";

    protected String me;

    public Dad() 
    {
       me = meInit;
    }

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

class Son extends Dad
{
    private static String meInit = "son";

    public Son()
    {
        me = meInit;
    }

}

public void doIt()
{
    new Son().printMe();
}
answered Sep 10, 2015 by DorieAckley
0 votes

Why would you want to override variables when you could easily reassign them in the subClasses.

I follow this pattern to work around the language design. Assume a case where you have a weighty service class in your framework which needs be used in different flavours in multiple derived applications.In that case , the best way to configure the super class logic is by reassigning its 'defining' variables.

public interface ExtensibleService{
void init();
}

public class WeightyLogicService implements ExtensibleService{
    private String directoryPath="c:\hello";

    public void doLogic(){
         //never forget to call init() before invocation or build safeguards
         init();
       //some logic goes here
   }

   public void init(){}    

}

public class WeightyLogicService_myAdaptation extends WeightyLogicService {
   @Override
   public void init(){
    directoryPath="c:\my_hello";
   }

}
answered Sep 10, 2015 by MiquelFraser

...