11

I tried to upcast an objet. But at runtime object class is remained as a derived class.

Derived drv = new Derived();

Base base = (Base) drv;

System.out.println("Class : " + base.getClass()); 

//prints -> Class : class packagename.Derived

So Why class property didn't change?

Huseyin
  • 163
  • 8

3 Answers3

15

So Why class property didn't change?

Because the object hasn't changed, just the type of the reference you have to it. Casting has no effect at all on the object itself.

In Java, unlike some other languages (thankfully), the type of the reference largely doesn't affect which version of a method you get. For instance, consider these two classes (courtesy of 2rs2ts — thank you!):

class Base {
    public Base() {}
    public void foo() {
        System.out.println("I'm the base!");
    }
}

class Child extends Base {
    public Child() {}
    public void foo() {
        System.out.println("I'm the child!");
    }
}

This code:

Child x = new Child();
Base y = (Base) x;
y.foo();

...outputs

I'm the child!

because even though the type of y is Base, the object that we're calling foo on is a Child, and so Child#foo gets called. Here (again courtesy of 2rs2ts) is an example on ideone to play with.

The fact that we get Child#foo despite going through a Base reference is crucial to polymorphism.

Now, it just so happens that the method you were calling (getClass) can only be Object#getClass, because it's a final method (subclasses cannot override it). But the concept is crucial and I figured it was probably the core of what you were asking about.

The chief thing that the type of the reference does is determine what aspects of an object you're allowed to access. For instance, suppose we add bar to Child:

class Child extends Base {
    public Child() {}
    public void foo() {
        System.out.println("I'm the child!");
    }
    public void bar() {
        System.out.println("I'm Child#bar");
    }
}

This code won't compile:

Child x = new Child();
Base y = (Base) x;
y.bar(); // <=== Compilation error

...because Base has no bar method, and so we can't access the object's bar method through a reference with type Base.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • **Base base = (Base) drv;** does not *convert* the **Derived**-type object pointed by **drv** into a **Base**-type object. It simply states that the **Derived**-type object can be *treated* as a **Base**-type object, and can perform everything a **Base**-type object can. – NoName Jun 21 '17 at 05:30
  • @NoName: The word "convert" doesn't appear anywhere in the answer. – T.J. Crowder Jun 21 '17 at 07:05
  • @T.J. Crowder: Oops, you may have misunderstood my comment as a correction to your answer. I am merely trying to clarify the way of thinking for a cast. – NoName Jun 21 '17 at 18:25
  • 1
    @NoName: Okay. I thought I covered that fairly well in the actual answer. – T.J. Crowder Jun 22 '17 at 07:33
0

You can not change the type of an instance in Java. All you're doing with your cast is reference it from a variable of a different type.

Andres
  • 10,561
  • 4
  • 45
  • 63
  • You mean "... the type of an **object** ..."? An instance is the reference variable pointing to the object. – NoName Jun 21 '17 at 05:26
  • Well...no. https://stackoverflow.com/questions/5531254/object-vs-instance https://stackoverflow.com/questions/2885385/what-is-the-difference-between-an-instance-and-an-object – Andres Jun 21 '17 at 08:58
0

An upcast does not change the object's type. As a matter of fact, NOTHING changes a Java object's type.

That's the very core of OO programming: An object has a defined behavior that can't be influenced from the outside.

Ray
  • 3,084
  • 2
  • 19
  • 27
  • `An object has a defined behavior that can't be influenced from the outside.` Not quite :) – Marko Topolnik Mar 18 '14 at 13:08
  • OK, it cannot be OVERRIDDEN or bypassed from the outside. Better? – Ray Mar 18 '14 at 13:10
  • The intentions behind OOP are one thing; Java's semantics something quite different. Specifically, reference casting doesn't have much to do with the defined behavior of objects. It's about *references* vs. *objects*. – Marko Topolnik Mar 18 '14 at 13:15
  • @T.J. Crowder: No, we're talking about an upcast here: http://forum.codecall.net/topic/50451-upcasting-downcasting/ – Ray Mar 18 '14 at 13:17
  • @Marko Topolnik The original question was, why the cast didn't influence the outcome of getClass(). This is related to the object's behavior, isn't it? – Ray Mar 18 '14 at 13:19
  • The question may be about behavior, but not the answer. If a class has a public field named the same as a field in its superclass, then the upcast *will* change the outcome. Explaining that with a blanket statement such as yours doesn't provide teaching value. – Marko Topolnik Mar 18 '14 at 13:23