• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Polymorphism reference variable question

 
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm trying to understand polymorphism and I'm confused about what it means when a reference of a class holds a reference to one of its subclasses. For example:







Is Mustang a Car or a Ford, or both??? And why would it be necessary for a Mustang to be a Car when the Ford object would have more details and specific methods in it. It seems as though Ford would be more useful since it already holds all the information that a Car holds, so why reference from a Car object?

If anyone has a simple explanation and example that would be helpful.

Ps: I've looked over other posts and found topics related to this but I'm probably not advanced enough to understand even those explanations.

Thanks,
Von
 
Ranch Hand
Posts: 2066
IntelliJ IDE Clojure Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vonique Leary wrote:
Is Mustang a Car or a Ford, or both???


Both, Mustang IS-A Ford IS-A Car

Vonique Leary wrote:
And why would it be necessary for a Mustang to be a Car when the Ford object would have more details and specific methods in it. It seems as though Ford would be more useful since it already holds all the information that a Car holds, so why reference from a Car object?



Ford is most specific object in that context, but basically it's a Car, It can do what a Car does.
 
lowercase baba
Posts: 13089
67
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
when you say "Car Mustang = new Ford();" a couple of things happen.

an object gets created somewhere. In this case, you get one of type "Ford".

You ALSO create a REFERENCE. This is a pointer to the actual object, not the object itself. Think of this as an address card in a rolodex. You write "Mustang" across the top for the name, and then the JVM writes the location of the actual object on that card.

As long as the actual object created is of the type declared, or one of it's subtypes, you are ok. So in your above example, you have a reference variable named "Mustang" that can point to ANY Car object, or any of it's subclasses. Since a Ford IS-A Car, this example is ok.

Is Mustang a Car or a Ford, or both???


Mustang is neither a Car, or a Ford. It is a REFERENCE to a Car, or one of it's subclasses.

This is confusing for beginners. I remember struggling with it myself. But it comes in handy when you don't really know what exactly you'll be getting. This is common when you are looking at everything in a collection, or when your code has to talk to code written by someone else.

Say you have a collection of cars, and you want to Start() each one. It's convenient to do this:


rather than this:


Further, if in the future you want to add the Tesla, the first example would not need to be changed. the second example requires you to add in code to handle the Tesla class.
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

FYI... the OP never showed us the class hierachy. We actually can't be sure if the assignment is valid or not.

Henry
 
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
(And to be honest, I'm skeptical if car brand belongs in the hierarchy; seems more of a mixin than anything else.)
 
fred rosenberger
lowercase baba
Posts: 13089
67
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:
FYI... the OP never showed us the class hierachy. We actually can't be sure if the assignment is valid or not.

Henry


True...I just assumed that for the sake of the example, it was legal.
 
Ranch Hand
Posts: 276
Netbeans IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok..let me try explaining this concept..reference and object
Consider this,

In Java, it is the type of reference variable and not the type of object that it refers to determines what members can be accessed.

So,in your case,

Its like....you make a Ford car, take away its logo. Anyone seeing it will just tell - 'Its a car!' - it has an engine,transmission etc. Only you and I know its engine,transmission system,etc. belong to Ford - nobody can go in and look at what make it is!

Am I making sense? Hope this helps..
 
Ranch Hand
Posts: 525
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Vonique : Polymorphism is confusing in part because there are really two ideas that
interact: 1) a child class can have more behaviors than its parent (additional methods),
and 2) a child class can override parent behaviors, doing what the parent does but in
its own unique way.

By saying "Parent x = new Child1()" you are telling the compiler that for variable 'x' you
intend to use only those methods defined in Parent. Any extra methods that Child1 may
have are off limits. So the methods available are controlled by the variable type (Parent).

We know that all classes that extend Parent will have at least Parent's set of methods.
So for example, Child2 or Child3 could also be assigned to variable 'x'. And this is where
polymorphism comes in. x.eat() for Child2 can be very different from x.eat() for Child3;
they each override the eat() method. And x.eat() for Child1 may be just as Parent would
expect (no override). So which eat() method is actually called depends on the class of
the 'x' object. The compiler will allow any object with Parent behaviors (or more) to be
assigned to 'x'.

Jim ... ...
 
fred rosenberger
lowercase baba
Posts: 13089
67
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I like how Bert and Kathy describe it in "Head First Java". They liken the reference variable to a remote, and the object to a TV. You can have a FancyTV or a PlainTV. You can also have a corresponding FancyRemote or PlainRemote.

The PlainRemote has buttons for volUp, volDown, channelUp, channelDown, and power(). The FancyRemote has all these, and also has picInPic, gotoChan(int), and a bunch of other options.

You can use a PlainRemote to point to a FancyTV, but you can't access the picInPic option. It's there on the object, but since the remote doesn't have the button, you can't press it and use that feature.
 
Vonique Leary
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

By saying "Parent x = new Child1()" you are telling the compiler that for variable 'x' you
intend to use only those methods defined in Parent. Any extra methods that Child1 may
have are off limits. So the methods available are controlled by the variable type (Parent).



Okay then why couldn't you just say Parent x = new Parent(); instead of Parent x = new Child(); if you only want Parent's methods?


I have the Head First book, I'll have to check it out. But the question still stands as to why wouldn't you just use the remote that allows the PicInPic feature?

Is it that you might want to use the Child class but limit the method choices to the Parent's? That makes sense but I can't think of an example of why you would want to do that, limit the choices I mean.


Or is it because of the ability to override from the base class?
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because you might be passing it to a method that expects to operate on a class or its subclasses:can accept either a Parent or a Child. This is the basis for a lot of OOP stuff, like:where Circle, Square, Triangle, etc. would all be a subclass Shape (for the purposes of this thread).
 
Vonique Leary
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, I get it now. Because if it wants a Shape, it will take a Square, Circle, Triangle, or etc. Now that I get it, it seems pretty simple.

Thanks everyone for all the explanations! Very helpful, as usual.

Vonique
 
Jim Hoglund
Ranch Hand
Posts: 525
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Excellent questions. This is where I am also just beginning to understand how polymorphism
can be used. I will try to construct a reasonable scenario. How about the TV remote control
mentioned above?

Let's say that interface BasicControl declares methods: on(), off(), volume() and channel() and
also that class RemoteV1 implements this interface; nothing extra, just the declared functions.
The methods available on 'x' would be the same for either "BasicControl x = new RemoteV1()"
or "RemoteV1 x = new RemoteV1()". But since we've been told to "design to the interface", we
deploy our program with the first "interface" definition.

Now it's time for an upgrade, adding methods mute() and sleepTimer(). Let's declare the new
methods in interface BetterControl which extends BasicControl. The new implementing class will
be RemoteV2 which extends RemoteV1. Also, let's say that an improved channel() method has
been developed and will be included in RemoteV2.

So what do we have? In writing RemoteV2 we didn't disturb the validated RemoteV1 methods
as they were inherited. The new mute() and sleepTimer() methods were coded and validated.
We decided, however, to include an overriding channel() method with better performance. Older
remotes can be upgraded by replacing RemoteV1 references with RemoteV2 and no other changes.
This works because "BasicControl x = new RemoteV2()" will work fine; even better because
RemoteV2 provides an improved channel() method (override).

New remotes will need "BetterControl x = new RemoteV2()" to access the new methods. Plus other
program changes to take advantage of the new behaviors.

Jim ... ...
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic