Roy
Roy

Reputation: 537

Method overriding and inheritance

public class Circle {

    public static final double PI = 3.141592654;
    protected double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public String toString() {
        return "Class = " + getClass().getSimpleName() + " (radius = " + radius + ")";
    }
}


public class PlaneCircle extends Circle {

    private double centerX, centerY;

    public PlaneCircle(double radius, double centerX, double centerY) {
        super(radius);
        this.centerX = centerX;
        this.centerY = centerY;
    }

    @Override
    public String toString() {
        return super.toString();
    }
}

Suppose the above two classes are in different files.

When I create an instance of PlaneCircle (in another java file) like the following two lines...

PlaneCircle planeCircle1 = new PlaneCircle(3, 6, 7);
System.out.println(planeCircle1.toString());

What I get in the Console output is

Class = PlaneCircle (radius = 3.0)

The toString() method in PlaneCircle calls super.toString(), and the toString() method in Circle should give "Circle" when I use the getClass().getSimpleName().

My question is, why the output is "PlaneCircle" instead of "Circle" in this case even though I have created an instance of the subclass (PlaneCircle)? Does this have anything to do with reflection?

Upvotes: 2

Views: 1531

Answers (3)

Brice Djilo
Brice Djilo

Reputation: 1

Since you are operating on an instance of PlaneCircle and not Circle, getClass.getSimpleName() will be called on your current instance of PlaneCircle. With the current setup you may not be able to print "Circle" using polymorphic behavior. At Runtime, methods of PlaneCircle will be called.

Upvotes: 0

Mureinik
Mureinik

Reputation: 310983

getClass() is also polymorphic - it returns a Class object that represents the instance it belongs to, in this case, a PlaneCircle. If you don't want this behavior, you could either hard code Circle:

@Override
public String toString() {
    return "Class = circle (radius = " + radius + ")";
}

Or statically access the Circle class:

@Override
public String toString() {
    return "Class = " + Circle.class.getSimpleName() + " (radius = " + radius + ")";
}

Upvotes: 1

Eran
Eran

Reputation: 393771

planeCircle1 is an instance of PlaneCircle, which means getClass() would return PlaneCircle.class (i.e. the Class instance that represents the PlaneCircle class) and getClass().getSimpleName() would return that class's name - "PlaneCircle".

It doesn't matter that getClass().getSimpleName() is called from a method of the base class Circle, since when you call a method without an instance variable, you are calling it on the current instance (i.e. getClass() is the same as this.getClass(), and this is an instance of PlaneCircle in your code sample).

Upvotes: 4

Related Questions