Search code examples
javapolymorphism

Is java67.com wrong on polymorphism?


Here's an example taken from their site:

An example of Polymorphism in Java Difference between Polymorphism, Overloading and Overriding in Java with ExampleLet's see a short example of Polymorphism in Java. In this example, the Pet variable behaves polymorphically because it can be either Cat or Dog. this is also an example of method overriding because the makeSound() method is overridden in subclass Dog and Cat.

import java.util.ArrayList;
import java.util.List;

abstract class Pet{
    public abstract void makeSound();
}

class Cat extends Pet{

    @Override
    public void makeSound() {
        System.out.println("Meow");
    }  
}

class Dog extends Pet{

    @Override
    public void makeSound() {
        System.out.println("Woof");
    }
 
}

Let's test How the Polymorphism concept works in Java:

/**
 *
 * Java program to demonstrate What is Polymorphism
 * @author Javin Paul
 */
public class PolymorphismDemo{

    public static void main(String args[]) {
        //Now Pet will show How Polymorphism work in Java
        List<Pet> pets = new ArrayList<Pet>();
        pets.add(new Cat());
        pets.add(new Dog());
     
        //pet variable which is type of Pet behave different based
        //upon whether pet is Cat or Dog
        for(Pet pet : pets){
            pet.makeSound();
        }
   
    }
}

Output:
Meow
Woof

In Summary, you can not compare Polymorphism with method overloading or override. Polymorphism is the ability of a variable to behave differently based upon which kind of Object it is referring to. They are Java programming language's way to implement polymorphism in language.

In the second example is the author just trying to make the point that at runtime we don't know what the objects are going to be? but this also includes an example of overriding?

Read more: https://www.java67.com/2012/10/difference-between-polymorphism-overloading-overriding-java.html#ixzz7rRlx0PQY

So is this a form of overriding or not?


Solution

  • A term is a way to ease communication. My brain thinks of a notion and I wish to convey it to your brain. My brain comes up with some words that encompass the notion I am trying to convey. I make my mouth move and my voicebox, shaking air comes out, they reach your ears, from there to your brain, and from there you decode the audio message.

    The communication is succesful if the notion you think I'm trying to convey is roughly equivalent to what I was actually trying to convey.

    And that is all that these terms are good for.

    It's clear that you're just hopelessly confused (this isn't the first question you're asking about it). Why do you 'care'? You do not need to know what the word 'override' is supposed to mean, you merely need to know the concept and the rules as the JVM / javac applies them. You can all this 'overriding', or you can call it 'floobargling' for all I care. As long as it is clear to you.

    If you don't even understand what the book is trying to tell you about these concepts, then 'let me try to ask some java programmers what they think this term means, and then if they think this java language feature is an application of what they think this term means' isn't going to get you any closer to understanding it.

    Specifically, 'polymorphism' is useless here. It's a nebulous term that people use to describe orthogonal concepts. In the job of conveying notions from brain to voice (or keyboard, if you prefer) to ears to another brain, summarizing notions by using the term 'polymorphism' is likely going to lead to failure to communicate.

    Override and Overload on the other hand are much better defined: These terms explicitly used in the Java Language Specification to mean very specific things in the context of java. Whether you feel these are 'forms' or 'examples' of polymorphism depends entirely on what you feel the term means. I don't see why it is relevant to know. Possibly you have some understanding of the notion of having the same code do different things depending on what you provide as input to this code, and that this is 'polymorphism', and you are trying to figure out what java's concepts of 'overload' and 'override' mean, in which case I suggest you just.. learn what those terms mean. Instead of praying that you ask somebody if these are 'forms of polymorphism' and that they have the same understanding of what polymorphism means as you do.

    Or perhaps this is some sort of homework exercise where you need to write an essay about it all, in which case, the advice is mostly the same. Try to understand the concepts, don't worry so much about what terms to use.

    overriding

    In java, for methods only (not constructors, not fields), any type can define an entirely new method. A method has an 'identity' and that identity is defined by both its name as well as all its parameter types, and at least at the class file level, even its return type. In contrast, if you define a method whose identity matches exactly with a method identity from a class or interface that is a supertype, then you aren't defined a new method, you are overriding the method from the supertype. At the language level (so, what javac does), a tightened return type is still an override (but that doesn't count for parameter types), and generics do not factor into this at all (because at the runtime level, i.e. class files and java.exe, generics do not exist). So:

    class Parent {
      Object foo(String a) {
        System.out.println("In parent");
        return null;
      }
    }
    
    class Child extends Parent {
      String foo(String b) {
     // This is an override
        System.out.println("In child");
        return null;
      }
    }
    

    Java does 'dynamic dispatch', meaning: Whenever you invoke a method, the most specific override available is actually invoked. It's about the actual type of the object that is referred to by your expression, and not about the expression's type. Thus:

    Parent p = new Child();
    p.foo("");
    

    prints "In child". Even though the type of p is parent, if you follow the pointer, p turns out to actually be pointing at an instance of Child, and Child's foo() impl is more specific. And therefore, is used. You can't tell java not to do this - only Child itself could (by invoking super.foo(a) to explicitly invoke the parent's implementation of foo(). You can't do something like p.super.foo(""), that isn't legal java.

    Overloading

    As I mentioned, the identity of a method includes its parameter types. Thus, given:

    class Parent {
      void foo(String a) {
        System.out.println("in Parent");
      }
    }
    
    class Child extends Parent {
      void foo(Object b) {
        System.out.println("in Child");
      }
    }
    

    These are completely different methods. As different as a method named 'jane' and another method named 'aubrey' - utterly, completely unrelated.

    Parent p = new Child();
    p.foo(null);
    

    That would compile and print 'In Parent'. Because given that p is of type Parent, the only foo method that foo(null) could possibly be referring to, is the foo(String) method that is in Parent, so that is invoked. At runtime the system dutifully goes looking for the most specific implementation of it, which is Parent's foo - because the foo in child is a completely different method. After all, its identity doesn't match.

    If you tried this:

    Child c = new Child();
    c.foo(null);
    

    There are 2 completely different methods but either one could feasibly be called. Javac will refuse to compile it and tell you this is an ambiguous method invocation (javac isn't clear which one you wanted). The key difference is that in this second example, there are 2 different methods, whereas in the first (where we are overriding), there is only one method identity, and 2 implementations of that identity.

    Given that these are 2 different methods, it's the compiler that needs to translate p.foo() into a class file, and as part of that job, it needs to name the full method identity of what you are attempting to invoke: Javac figures out which of a bunch of overloads you meant to call.

    So, which one is polymorphism?

    That depends entirely on what you mean by 'polymorphism'. The java lang spec doesn't use that word, a java programmer therefore doesn't need to care about that word. The first example is overriding. The second is overloading. I don't see what the point is of bringing a nebulous, ill-defined term in the mix.