slomir
slomir

Reputation: 171

Inheritance and the "this" keyword

Suppose that we have next situation:

Parent class A:

class A{  
    public A(){}
    public doSomething(){  
        System.out.println(this.getClass());
    }
}

with a child class B:

class B extends A{  
    public B(){}
    public void doSomething(){
        super.doSomething();
        System.out.println(this.getClass());
    }
}

and Main class:

class Main{  
    public static void main(String[] args){
        A ab=new B();
        ab.doSomething();
    }
}

When I execute this code result is

B  
B

Why does this, referenced in superclass A, returns B as a class when the reference is of type A?

Upvotes: 17

Views: 11019

Answers (5)

shivani
shivani

Reputation: 1

The output of program is correct.

When in Main class ab.doSomething(); line get executed doSomething() method of class B will be called then super.doSomething(); line will call doSomething() method of class A. As this keyword indicates reference of current object(ab is the object of class B see A ab=new B(); as constructor is of class B),i.e.System.out.println(this.getClass()); line in class A will print B only.

Again control will come back to System.out.println(this.getClass());in class B, So again B will get print.

In birdeye view only object of class B has created. That is why we are getting B B in output.

Upvotes: 0

user638455
user638455

Reputation:

Think of it in terms of runtime vs static types:

Animal a = new Cat();

The static type (in this case written on the left hand side) of variable a is Animal (you couldn't pass a into a method that required a Cat without a downcast) but the runtime type of the object pointed to by a is Cat.

a.getClass() exposes the runtime type (if it helps think of it as the most specific subtype).

Interestingly in Java overloaded methods are resolved at compile-time (without looking at the runtime type). So given then following two methods:

foo(Cat c);
foo(Animal animal)

Calling foo(a) would call the latter. To 'fix' this the visitor pattern can be used to dispatch based on the runtime type (double dispatch).

Upvotes: 2

justkt
justkt

Reputation: 14766

Despite the fact that you are calling the doSomething() method of A, the this during that call is a B, and so the getClass() method is called on B not on A. Basically the this will always be a B whether you are using a method from superclass A, a method from B, or from A's superclass Object (the parent class of all Java classes).

Upvotes: 5

Tom Jefferys
Tom Jefferys

Reputation: 13310

It doesn't matter what the reference is, it's the instantiated object's class that counts. The object that you're creating is of type B, therefore this.getClass() is always going to return B.

Upvotes: 21

jzd
jzd

Reputation: 23629

this doesn't do anything for you in this situtaion. Calling this.getClass() is no different than just calling getClass();

So, A calls getClass(), which will return B if you are dealing with an instance of B that extends A.

Upvotes: 4

Related Questions