Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Java handle fields when upcasting? [duplicate]

Tags:

java

Possible Duplicate:
The concept of shadowing

I am confused about how the fields of classes are handled in Java during upcasting. For example:

class SuperClass
{
    String myString = "String in SuperClass";

    public void myMethod()
    {
        System.out.println("Method in SuperClass");
    }
}

class SubClass extends SuperClass
{
    String myString = "String in SubClass";

    public void myMethod()
    {
        System.out.println("Method in SubClass");
    }
}

class Question
{
    public static void main(String[] args)
    {
        SuperClass test = new SubClass();
            // object test is an instance of SubClass
            // but I am telling the compiler to treat it as SuperClass

        test.myMethod();
        System.out.println(test.myString);

    }
}

Output:

Method in SubClass
String in SuperClass //Why is "String in SubClass" not used?

When I create an object test it is an instance of SubClass class; however, I am telling the compiler to treat it as SuperClass. Everything is clear to me about methods work: I will only be able to use the methods of the SubClass, if a given method is defined for SuperClass.

However, I am lost as to why a field of a SuperClass is used when I try to access myString of test. Since test is an instance of SubClass I would expect myString defined in SubClass to be used, why is this not happening? What am I missing?

I know that I can access, myString of SubClass by using this operator. For example, I could define printMyString method in SuperClass, and overwrite it with

public void printMyString()
{
    System.out.println(this.myString);
}

In the SubClass, so my question is mostly about how come the field of the SuperClass is used in test. Maybe I am missing something obvious?

I tried to search for the answer, and the closest topic I found was Upcasting in Java and two separate object properties, though helpful, it did not answer my question.

Thank You in Advance

like image 893
Akavall Avatar asked Jan 01 '13 06:01

Akavall


People also ask

Is Upcasting possible in Java?

Upcasting: Upcasting is the typecasting of a child object to a parent object. Upcasting can be done implicitly. Upcasting gives us the flexibility to access the parent class members but it is not possible to access all the child class members using this feature.

What is the difference between Upcasting and downcasting in Java?

What are Upcasting and Downcasting in Java? Upcasting (Generalization or Widening) is casting to a parent type in simple words casting individual type to one common type is called upcasting while downcasting (specialization or narrowing) is casting to a child type or casting common type to individual type.

Is Upcasting safe?

It means the upcasting used to convert the reference or pointer of the derived class to a base class. Upcasting is safe casting as compare to downcasting. It allows the public inheritance that implicitly cast the reference from one class to another without an explicit typecast.

Why do we need Upcasting and downcasting in Java?

Why we need Upcasting and Downcasting? In Java, we rarely use Upcasting. We use it when we need to develop a code that deals with only the parent class. Downcasting is used when we need to develop a code that accesses behaviors of the child class.


2 Answers

Attributes cant be overloaded like methods.

test.myMethod(); 

Here method invocation depends on the type of actual object. Here object is of type SubClass so method of SubClass is invoked.

test.myString

While accessing attributes,it depends on the type of reference variable. Here reference variable ie test is of type SuperClass so attribute from SuperClass is accessed.

What you are looking is class variable hiding / shadowing.

like image 119
Ajinkya Avatar answered Sep 23 '22 02:09

Ajinkya


Fields in Java are only hidden and not actually overridden (that doesn't mean that we'll get a compile time error while trying this, instead they are not overridden in its true sense).

Overriding means the member should be invoked based on the run time type of the object and not based on the declared type.

But binding for fields in Java is always static and hence it's based on the declared type of the object reference only.

In the example you've given, by declaring the class variable with the name 'myString' in class SubClass you hide the class variable it would have inherited from its superclass SuperClass with the same name 'myString'.

Java language specification :

If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class.

A hidden field can be accessed by using a qualified name if it is static, or by using a field access expression that contains the keyword super or a cast to a superclass type.

like image 29
Rahul Avatar answered Sep 21 '22 02:09

Rahul