• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Liutauras Vilda
  • Campbell Ritchie
  • Tim Cooke
  • Bear Bibeault
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Knute Snortum
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Ganesh Patekar
  • Stephan van Hulst
  • Pete Letkeman
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Ron McLeod
  • Vijitha Kumara

Inheritance and Polymorphism!  RSS feed

 
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was trying out an example of polymorphism with the following code:-



But here i noticed when we run the code the output is :-

java Splendor
running safely with 60km
running
running safely with 60km


So my question is when Bike b = new Splendor(); & Splendor d = new Splendor(); give the same output i.e. "running" then what is the need to upcasting the reference variable 'b' ?

and what does it helps in?

Regards,
MANISH
 
Greenhorn
Posts: 27
Android Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you upcast splendor to bike you can only use the methods defined in bike. But there is always used the implementation of the original class i.e. of splendor. That is useful for example if a method takes a parameter of type bike and you want to put a splendor.
 
Marshal
Posts: 60168
188
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What makes you think you are casting any references?
I am dubious about your inheritance tree. Is Splendor a kind of Bike? (Motor or pedal?) Or is it a make of bike? In which case are you going to have class Kawasaki extends Motorbike or class Yamaha extends Motorbike or class BMW extends Motorbike? But a BMW isn't simply a bike; it might be a car as well. So I am dubious about the concept that a make should be a subclass of Bike.
Any way, back to the question you actually asked. You are not casting anything. Remember that your Splendor class has three types: Splendor, Bike and Object. You can assign it to any of those references without casting because it already has those types. It is never necessary to cast anything to a more general type or a “wider” type, sometimes called upcast. It is a bit more complicated if you have an inheritance hierarchy like this:-
class Car extends Vehicle and class Taxi extends Car
Now you have a Car reference:-You can guarantee that a taxi is a car but you cannot be certain that a car is a taxi, so my lines 2‑3 don't compile. The only way you are going to get that sort of thing to compile is like this:-That is a cast, casting to a more specific type or a “narrower” type, sometimes called a downcast. If you need to do that, the castis essential. You are telling the compiler,

I promise that whichever Car I “get()”from that list will be a Taxi

...and the compiler will believe you. All will be well until the car object is a plain simple car and not a taxi.
The type of the reference determines how many methods you can call. Try putting these methods into the appropriate classes:-
  • Vehicle has run()
  • Car has getPassengerNumber()
  • Taxi has getFare(int distance)
  • Now try the following:-Now, you will see that the compiler won't let you call the specific Car method on a Vehicle reference, but it will let you call toString(), which is inherited from Object, on everything. So the reference determines number of methods available but for version of method called, watch this space for a new post.
     
    Campbell Ritchie
    Marshal
    Posts: 60168
    188
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    So, the declared type determines how many methods are available, but the runtime type determines which version is called. You cannot necessarily determine the runtime type in advance. What if you have keyboard input like this:-It is now impossible to know in advance what sort of vehicle you are going to get. Now, which version of the run() method are you going to use? Because the compiler has already checked the Vehicle class and “knows” that there will be a run() method but cannot determine which version to call. The compiler doesn't therefore determine this: what you get is called late binding or runtime binding; I think runtime binding is a better term. The compiler leaves the actual choice of method to the runtime. The JVM finds the Class<XYZ> which the instance was created from. If it happens to be a Splendor object, then it looks in the Class<Splendor> object for a run() method. If it finds it, that is the method used. If it doesn't find it, it “knows” there will be a version in a superclass somewhere; it can actually find the superclass' methods by going through the Class<Splendor> object and looking for superclasses. The JVM will eventually find a fully‑implemented version and it will use the first version found. That means if your runtime type is a more specialised or “narrower” type, the more specialised version of the method is used.

    Beware: polymorphism only applies to instance methods, not to fields nor static methods, so it is potentially dangerous to try declaring static methods and fields with the same name in subclasses. They are bound at compile time.
     
    Campbell Ritchie
    Marshal
    Posts: 60168
    188
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    A few minutes ago, I wrote:. . . . The JVM will eventually find a fully‑implemented version . . . .

    Challanges:-
  • 1: Work out how the JVM “knows” that there is a fully‑implemented version of that method available.
  • 2: Work out how to break the code by removing that fully‑implemented method Naughty suggestion.
  •  
    Ben Ernstberger
    Greenhorn
    Posts: 27
    Android Java Netbeans IDE
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thank you for that good explanation. I've learned a lot and I already solved the first challenge (I don't say it to let others solve it too). Unfortunately my English is to bad to get a meaningful translation of the second challenge. I don't get what you mean with "break code".
     
    Campbell Ritchie
    Marshal
    Posts: 60168
    188
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Change it so it fails to run normally at runtime.
     
    Sheriff
    Posts: 12355
    201
    Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Ben Ernstberger wrote:I don't get what you mean with "break code".


    When code is broken, that means it doesn't work the way it should. That or it fails to even compile.
     
    Manish Pamnani
    Ranch Hand
    Posts: 56
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator


    SO it means i can inherit any number of subclasses from superclass?
    Will there be no affect on running time of my program as it would have so many classes?
     
    Sheriff
    Posts: 23714
    50
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Manish Pamnani wrote:SO it means i can inherit any number of subclasses from superclass?



    Pretty much so, yes. Although if you wrote something to generate a subclass hierarchy which is 2,000,000 levels deep you might run into some kind of limit. You could try that if you liked, you might get a better answer than this one here.

    Will there be no affect on running time of my program as it would have so many classes?



    Compared to some other program which has fewer classes? Maybe there would. But why would that matter?
     
    Campbell Ritchie
    Marshal
    Posts: 60168
    188
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Paul Clapham wrote:. . . But why would that matter?

    Execution speed should probably be the last consideration when designing an app. It is much more important to get the number of classes rright, and any inheritance hierarchy. It might be slightly slower to compile more classes, but that is the least of our worries.
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!