DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Singleton: 6 Ways To Write and Use in Java Programming

Trending

  • Mastering Fluent Bit: Installing and Configuring Fluent Bit on Kubernetes (Part 3)
  • Scaling DevOps With NGINX Caching: Reducing Latency and Backend Load
  • Kubeflow: Driving Scalable and Intelligent Machine Learning Systems
  • Beyond ChatGPT, AI Reasoning 2.0: Engineering AI Models With Human-Like Reasoning

Why the Instance Variable of the Super Class Is Not Overridden in the Sub Class

Need help understanding why the instance variable of the super class is not overridden in the subclass? Check out this post where we answer this question.

By 
Naresh Joshi user avatar
Naresh Joshi
DZone Core CORE ·
Updated Sep. 07, 20 · Analysis
Likes (20)
Comment
Save
Tweet
Share
115.7K Views

Join the DZone community and get the full member experience.

Join For Free

When we create a variable in both parent and child classes with the same name and try to access it using a parent's class reference, which is holding a child class's object, then what do we get?

In order to understand this, let us consider the example below where we declare a variable x with the same name in both Parent and Child classes.

class Parent {
    // Declaring instance variable by name `x`
    String x = "Parent`s Instance Variable";

    public void print() {
        System.out.println(x);
    }
}

class Child extends Parent {

    // Hiding Parent class's variable `x` by defining a variable in child class with same name.
    String x = "Child`s Instance Variable";

    @Override
    public void print() {
        System.out.print(x);

        // If we still want to access variable from super class, we do that by using `super.x`
        System.out.print(", " + super.x + "\n");
    }
}


And now, if we try to access x using below code, System.out.println(parent.x) will print:

Parent parent = new Child();
System.out.println(parent.x) // Output -- Parent`s Instance Variable


Well generally, we say that the Child class will override the variable declared in the Parent class, and parent.x will give us whatever the Child's object is holding. Because it is the same thing, it happens while we do the same kind of operation on methods.

But, actually, it is not, and the parent.x will give us the value of the Parent`s Instance Variable, which is declared in the Parent class — but why?

This is because variables in Java do not follow polymorphism and overriding is only applicable to methods, not variables. And when an instance variable in a child class has the same name as an instance variable in a parent class, then the instance variable is chosen from the reference type.

In Java, when we define a variable in a Child class with a name that we have already used to define a variable in the Parent class, the Child class's variable hides the parent's variable, even if their types are different. And this concept is known as variable hiding.

In other words, when the child and parent class both have a variable with the same name, the Child class's variable hides the Parent class's variable. You can read more on variable hiding in the article: What is Variable Shadowing and Hiding in Java.




Variable Hiding Is Not the Same as Method Overriding

While variable hiding looks like overriding, a variable is not all that similar. Overriding is applicable only to methods, while hiding is applicable to variables.

In the case of method overriding, overriding methods completely replaces the inherited methods, so when we try to access the method from the parent's reference by holding the child's object, the method from the child class gets called. You can read more about overriding and how overridden methods completely replace the inherited methods on Everything About Method Overloading Vs Method Overriding and Why We Should Follow Method Overriding Rules.

But in variable hiding, the child class hides the inherited variables instead of replacing, which basically means is that the object of the Child class contains both variables, but the Child's variable hides the Parent's variable. So when we try to access the variable from within the Child class, it will be accessed from the child class.

And if I simplify the section Example 8.3.1.1-3. Hiding of Instance Variables of Java language specification:

When we declare a variable in a Child class, which has the same name, e.g. x as an instance variable in a Parent class, then:

  1. The Child class's object contains both variables (one inherited from the Parent class and another declared in Child itself) but the child class variable hides the parent class's variable.
  2. Because the declaration of x in class Child hides the definition of x in class Parent, within the declaration of class Child, the simple name x always refers to the field declared within class Child. And if the code in methods of theChild class wants to refer to the variable x of the Parent class, then this can be done as super.x.
  3. If we are trying to access the variable outside of the Parent and Child class, then the instance variable is chosen from the reference type. Thus, the expression parent2.x in the following code gives the variable value that belongs to the Parent class, even if it is holding the object of the Child. But,((Child) parent2).xaccesses the value from the Child class because we cast the same reference to Child.

Why Instance Variable Of Super Class Is Not Overridden In Sub Class due to variable shadowing










Why Variable Hiding Is Designed This Way

So, we know that instance variables are chosen from the reference type, not instance type, and polymorphism is not applicable to variables, but the real question is why? Why are variables designed to follow hiding instead of overriding?

This is because variable overriding might break methods inherited from the Parent if we change its type in the Child class.

We know every Child class inherits variables and methods (state and behavior) from its Parent class. Imagine if Java allows variable overriding and we change the type of a variable from int to Object in the Child class. It will break any method using that variable, and because the child has inherited those methods from the Parent, the compiler will give errors in the Child class.

For example:

class Parent {
    int x;
    public int increment() {
        return ++x;
    }
    public int getX() {
        return x;
    }
}

class Child extends Parent {
    Object x;
    // Child is inherting increment(), getX() from Parent and both methods returns an int 
    // But in child class type of x is Object, so increment(), getX() will fail to compile. 
}


If Child.x overrides  Parent.x, how can increment() and getX() work? In the subclass, these methods will try to return a value of a field of the wrong type!

And as mentioned, if Java allows variable overriding, then the  Child's variable cannot substitute the  Parent's variable, and this would break the Liskov Substitutability Principle (LSP).

Why Is the Instance Variable Chosen From a Reference Type Instead of an Instance?

As explained in How Does JVM Handle Method Overloading and Overriding Internally, at compile time, overriding method calls are treated from the reference class only, but all overridden methods get replaced by the overriding method at runtime using a vtable. This phenomenon is called runtime polymorphism.

Similarly, at compile time, variable access is also treated from the reference type, but as we discussed, variables do not follow overriding or runtime polymorphism, so they are not replaced by child class variables at the runtime and still refer to the reference type.

Generally speaking, no one will recommend hiding fields, as it makes code difficult to read and creates confusion. This kind of confusion will not always stick to General Guidelines to create POJOs and encapsulate our fields by declaring them as private and provides getters/setters as required, so the variables are not visible outside that class and the child class cannot access them.

You can find complete code on this GitHub repository. Please feel free to provide your feedback in the comments section below.

Instance variable

Published at DZone with permission of Naresh Joshi, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Singleton: 6 Ways To Write and Use in Java Programming

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!