Run-time Polymorphism in Java without “abstract”?

拥有回忆 提交于 2019-11-29 17:24:25

How is run-time polymorphism achieved unless printDescription() in Bicycle is declared "abstract"?

Why would you think abstract classes would change anything? Abstract classes do 2 primary things

  1. Allow the programmer to declare a class that cannot itself be instantiated, forcing subclassing, and
  2. Allow the programmer to force subclasses to provide implementations of methods, by declaring the method abstract.

Note that point 2 does not imply that polymorphism won't work unless a method is declared abstract on the base class; rather, it provides the developer an opportunity to force a subclass to provide an implementation, which is not required in subclassing scenarios that don't involve any abstract usage.

That's it. In other words, the notion of abstract compliments Java's polymorphism -- it is a language feature, but doesn't have anything to do with the dynamic dispatch Java uses at runtime to invoke methods. Anytime a method is invoked on an instance, the type of the instance at runtime is used to determine which method implementation to use.

virtual is a keyword in many languages that means "this method can be overridden by a subclass". Java does not have that keyword but instead all non static member methods are virtual and possible to override.

abstract is the same as virtual, except it tells the compiler that the base class does not have a definition for the method. It's useful at times if there is no useful function for the base class to perform, but it's by no means needed to be able to override the base class method.

In your case, the printDescription method has a useful definition for the base class, so there's no need to declare it abstract. It's virtual by default and therefor overridable by the subclass, so there is no need for a keyword to indicate that.

In Java all methods are bind at run-time (that's what you can achieve in C++ declaring a method virtual).

So the JVM can always dispatch the method correctly.

Actually the method binding in Java could never be static, because you are always dealing with references to objects (can't allocate an object on the stack, like C++). This actually force the JVM to always check the run-time type of an object reference.

There no need to declare that method abstract.. In runtime polymorphism, appropriate derived class method is invoked based on what class instance does the base class reference points to..

Consider the following example: -

class A {
    public void doSomething() {

    }
}

class B extends A {
    public void doSomething() {
         System.out.println("In B")
    }
}

public class Test {
    public static void main(String args[]) {
          A obj = new B();   // Base class reference and derived class object.

          obj.doSomething();  // Calls derived class B's method and prints `In B`
    }
}

To quote the statement that you read: -

the tutorial mentions the Java Virtual Machine (JVM) calls the appropriate method for the object that is referred to in each variable.

To justify the above statement, see the above example. There your B class method is invoked because your base class reference obj is pointing derived class B's instance..

Type of the reference pointing the object is always checked at compile time, whereas, the type of object pointed by that reference is checked at runtime..

So, the decision of which method will be invoked is made at runtime.. Regardless of the whether your base class method is abstract or not, appropriate derived class method is invoked..

This is not C++. In Java, you always know the real class of each instance so, when printDescription() is invoked, the definition of that class is used. Though, you can only use the methods available in the references to the instance (so, if you define a method getMPH() in class RoadBike and you handle an instance of that class with a Bike variable, the compiler will thow an error if you intend to use it).

I think this code:

bike01 = new Bicycle(20, 10, 1);       
bike02 = new MountainBike(20, 10, 5, "Dual");       
bike03 = new RoadBike(40, 20, 8, 23);        
bike01.printDescription();       
bike02.printDescription();       
bike03.printDescription(); 

is not the best example of run-time polymorphism because all facts (methods to call) are known even at compile time. But if you would change it to:

Random r = new Random();

if(r.nextInt(2)%2==0)
{
    bike01 = new Bicycle(20, 10, 1)
}
else
{
    bike01 = new MountainBike(20, 10, 5, "Dual");
}

// only at run-time the right function to call is known

bike01.printDescription();

...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!