Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding instance variables of a class

Tags:

java

oop

I'm wondering why Java has this strange behavior regarding a superclass and a subclass having instance variables with the same name.

Let's say we have the following class definitions:

class Parent {
    int var = 1;
}

class Child extends Parent {
    int var = 2;
}

By doing this, we are supposed to have hidden the superclass's variable var. And if we do not explicitly specify a way to access Parent's var via a super call, then we should never be able to access var from an instance of a child.

But when we have a cast, this hiding mechanism breaks:

Child child = new Child();
Parent parent = (Parent)child;
System.out.println(parent.var); // prints out 1, instead of 2

Doesn't this completely circumvent the whole point of field hiding? If this is the case, then doesn't that render the the idea completely useless?

EDIT: I am referring specifically to this article in the Java Tutorials. It mentions

Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super...

From what I read there, it seems to imply that the developers of Java had some kind of technique in mind in doing this. Though I agree that it is a rather obscure concept and would probably bad practice in general.

like image 650
tskuzzy Avatar asked Oct 17 '11 13:10

tskuzzy


People also ask

What is meant by instance variable hiding?

If the superclass and the subclass have instance variable of same name, if you access it using the subclass object, the instance variables of the subclass hides the instance variables of the superclass irrespective of the types. This mechanism is known as field hiding or, instance variable hiding.

How do you hide a class variable in Java?

The shadowed instance variable can be accessed using the this keyword. Variable hiding happens when a variable declared in the child class has the same name as the variable declared in the parent class. The hidden variable of the parent class can be accessed using the super keyword.

Can you make instance variables private?

Instance variables are encapsulated by using the private access modifier. Methods can be public or private, but they are usually public.

Should instance variables be private?

The instance variables are visible for all methods, constructors, and block in the class. Normally, it is recommended to make these variables private (access level). However, visibility for subclasses can be given for these variables with the use of access modifiers. Instance variables have default values.


2 Answers

In Java, data members are not polymorphic. This means that Parent.var and Child.var are two distinct variables that happen to have the same name. You're not in any sense "overriding" var in the derived class; as you have discovered yourself, both variables can be accessed independently of one another.

The best way forward really depends on what you're trying to achieve:

  1. If Parent.var should not be visible to Child, make it private.
  2. If Parent.var and Child.var are two logically distinct variables, give them different names to avoid confusion.
  3. If Parent.var and Child.var are logically the same variable, then use one data member for them.
like image 190
NPE Avatar answered Sep 22 '22 00:09

NPE


The "point" of field hiding is merely to specify the behaviour of code which does give a variable the same name as one in its superclass.

It's not meant to be used as a technique to genuinely hide information. That's done by making the variables private to start with... I would strongly recommend using private variables in virtually all cases. Fields are an implementation detail which should be hidden from all other code.

like image 28
Jon Skeet Avatar answered Sep 21 '22 00:09

Jon Skeet