javaobjecttostringobject-to-string

How does Object.toString() work for different underlying types?


I don't understand why this works in java:

If I have an Integer object in a object, example:

Object myIntObj = new Integer(5);

Now if i do:

System.out.println(myIntObj);

the output is: 5

I now that the Integer class has an ovveride of the toString method but in this case is different (I think). For the polymorphism, if I have a "child object" in a "father variable" the object doesn't change its real type (in this case Integer) But... it (in the Object variable) can just use the method of the Object Class, so why if I write:

System.out.println(myIntObj);

I can see directly the number 5 and not the reference of this object? Because toString method in the object class by default return just a string of the reference of the object.

like:

Object currentPlayer = new Player();
System.out.println(currentPlayer);

In this case the output is the reference of the Player objecet because is called the toString method in the object class.

So why in the example of before I don't see the reference but directly the number? by logic, the rules of the polymorphism says that: if u have a "child" object in a "father" variable, this object, inside, remanis the same but he is used like an istance of object, so he can just uses the class object and so just the method of object, so is really strange that I don't see the reference but directly the number.

I hope you understand what I mean.


Solution

  • Your last paragraph where you explain your reasoning is slightly incorrect.

    so why in the example of before i don't see the reference but directly the number? by logic, the rules of the polymorphism says that: if u have a "child" object in a "father" variable, this object, inside, remanis the same but he is used like an istance of object, so he can just uses the class object and so just the method of object, so is really strange that i don't see the reference but directly the number.

    The beginning is correct, but the part I bolded is an incorrect conclusion you drew from it.

    You are correct that with polymorphism, the object truly remains whatever type it is, but the reference type (the type of the variable) defines what you can do with it. However, the reference type does not describe what the object does

    That is the intent behind polymorphism. It is an abstraction to define what can be done separately from how it works. For example, if you have this example:

    public class Vehicle {
        public int getWheelCount() {
            return 1;
        }
    }
    
    public class Car extends Parent {
        public int getWheelCount() {
            return 4;
        }
    
        public void blowHorn() {
            System.out.println("Honk honk!");
        }
    }
    
    public class Bicycle extends Parent {
        public int getWheelCount() {
            return 2;
        }
    }
    
    Car car = new Car();
    car.getWheelCount();  // 4
    car.blowHorn();  //"Honk honk!"
    
    Vehicle v = new Car();
    v.getWheelCount()  // 4
    v.blowHorn();  // COMPILE ERROR HERE!  Unknown method
    
    Bicycle b = new Bicycle();
    b.getWheelCount();  // 2
    
    Vehicle v = new Bicycle();
    v.getWheelCount();  // 2
    

    What you can conclude from this is that when over-riding a method in a sub-class, the child version is always called. A car is always a car whether you are referring to it as a vehicle or as a car. But by referring to it as a vehicle, you are limited to invoking methods which are defined on all vehicles.

    To tie it to the example, all Vehicle objects have a wheel size, therefore getWheelCount() is always callable whether it's Vehicle.getWheelCount() or Car.getWheelCount(). However, Car.getWheelCount() is what executes because Car over-rides it.

    If the reference type is Vehicle, you cannot call blowHorn() because that method is only available on Car.

    Going back to your example, an Integer is an Integer.

    Object i = new Integer(5);
    i.toString();  // 5
    

    This prints 5 because i is an integer. The Integer class over-rides toString. The reference type (the type you are referring to the object as) only determines which methods you can call, but not which parent/child class's version of the method is called.