Is there a way to override class variables in Java?

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

17 Answers

Yes, just override the printMe() method:

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

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

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.

Variables don't take part in overrinding. Only methods do. A method call is resolved at runtime, that is, the decision to call a method is taken at runtime, but the variables are decided at compile time only. Hence that variable is called whose reference is used for calling and not of the runtime object.

Take a look at following snippet:

package com.demo;

class Bike {
  int max_speed = 90;
  public void disp_speed() {
    System.out.println("Inside bike");
 }
}

public class Honda_bikes extends Bike {
  int max_speed = 150;
  public void disp_speed() {
    System.out.println("Inside Honda");
}

public static void main(String[] args) {
    Honda_bikes obj1 = new Honda_bikes();
    Bike obj2 = new Honda_bikes();
    Bike obj3 = new Bike();

    obj1.disp_speed();
    obj2.disp_speed();
    obj3.disp_speed();

    System.out.println("Max_Speed = " + obj1.max_speed);
    System.out.println("Max_Speed = " + obj2.max_speed);
    System.out.println("Max_Speed = " + obj3.max_speed);
  }

}

When you run the code, console will show:

Inside Honda
Inside Honda
Inside bike

Max_Speed = 150
Max_Speed = 90
Max_Speed = 90

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

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.

No. Class variables(Also applicable to instance variables) don't exhibit overriding feature in Java as class variables are invoked on the basis of the type of calling object. Added one more class(Human) in the hierarchy to make it more clear. So now we have

Son extends Dad extends Human

In the below code, we try to iterate over an array of Human, Dad and Son objects, but it prints Human Class’s values in all cases as the type of calling object was Human.

    class Human
{
    static String me = "human";

    public void printMe()
    {
        System.out.println(me);
    }
}
class Dad extends Human
{
    static String me = "dad";

}

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


public class ClassVariables {
    public static void main(String[] abc)   {
        Human[] humans = new Human[3];
        humans[0] = new Human();
        humans[1] = new Dad();
        humans[2] = new Son();
        for(Human human: humans)   {
            System.out.println(human.me);        // prints human for all objects
        }
    }
}

Will print

  • human
  • human
  • human

So no overriding of Class variables.

If we want to access the class variable of actual object from a reference variable of its parent class, we need to explicitly tell this to compiler by casting parent reference (Human object) to its type.

    System.out.println(((Dad)humans[1]).me);        // prints dad

    System.out.println(((Son)humans[2]).me);        // prints son

Will print

  • dad
  • son

On how part of this question:- As already suggested override the printMe() method in Son class, then on calling

Son().printMe();

Dad's Class variable "me" will be hidden because the nearest declaration(from Son class printme() method) of the "me"(in Son class) will get the precedence.

Just Call super.variable in sub class constructor

public abstract class Beverage {

int cost;


int getCost() {

    return cost;

}

}`

public class Coffee extends Beverage {


int cost = 10;
Coffee(){
    super.cost = cost;
}


}`

public class Driver {

public static void main(String[] args) {

    Beverage coffee = new Coffee();

    System.out.println(coffee.getCost());

}

}

Output is 10.

Related