Search code examples
javainheritancepolymorphismsubclasssuperclass

Polymorphism and dealing with native types


I am trying to understand Polymorphism and the inheritance relationship between a superclass and its subclass. I know that when dealing with an object that's instantiated from the subclass either as its native type, the subclass or as it's inherited or to extend a type the Superclass. What is the objects native type? What are differences between the three types of Polymorphism?


Solution

  • Two terms that might help:

    • dynamic type
    • static type

    An object has a type, that is the type that comes after new. But when you have polymorphism, there are different ways to refer to the object:

    Integer v = Integer.valueOf(123);
    Number n = v;
    

    Here, n and v refer to the same object, but in different ways. This is allowed because Integer is a subclass of Number and Number is a superclass of Integer.

    Now, n has two different types. The static type, which is Number, which appears in the text of the program. It also has a dynamic type, which is Integer, which is its real type. I assume the real type, or the dynamic type, is what you mean by "native type".

    With this knowledge, we can look at the different types of polymorphism:

    Ad-hoc polymorphism (aka overloading in Java): You can have multiple functions with the same name and parameter lists, differing only by parameter type. Which function will be chosen will depend on the static type.

    public String add(String a, String b) {
        return a + b;
    }
    
    public int add(int a, int b) {
        return a + b;
    }
    
    add("a", "b"); // calls first version of add
    add(1, 2); // calls second version of add
    

    Parametric polymorphism (aka generics in Java): You can have the same functions "parameterized" by a type argument T. Which functions are available on T depend on the static type.

    public <T extends Number> boolean lessThan(T a, T b) {
        // compareTo is available because T has the static type Number
        return a.compareTo(b) < 0;
    }
    

    Subtype polymorphism (aka overriding): Which function is called depends on the dynamic type.

    public abstract class Animal {
        public abstract void speak();
    }
    
    public class Dog {
        public void speak() { System.out.println("Woof"); }
    }
    
    public class Cat {
        public void speak() { System.out.println("Meow"); }
    }
    
    Animal a = new Dog();
    Animal b = new Cat();
    a.speak(); // says Woof - because dynamic type is Dog
    b.speak(); // says Meow - because dynamic type is Cat