Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Polymorphism / Inheritence & Variable Declarations 3

Status
Not open for further replies.

1DMF

Programmer
Jan 18, 2005
8,795
0
0
GB
Ok, my brain is totally frazzled over this, partly because the courses system has a bug in it, and I came to completely the wrong conclusions then trying to understand inheritence...

So i'm hoping someone here can clear things up for me.

If I had a class ClassA & a sub-class of ClassA, called ClassB.

I understand that you can perfom the following...

Code:
ClassA myclass = new ClassB();

However the object instance referenced by myclass, although initialised as a ClassB object it is actually only a ClassA object and only instance attributes and methods from ClassA will be permitted / accesible. (in the course IDE, you can run methods of ClassB after creating the object as above, which apparently is wrong.) Hence my total confusion over all this.

So is the only reason a declared variable allows this is so you can use Polymorphism in your code and that is how polymorphic methods are exacutable, by allowing a required variable type to be passed as an argument, that is declared as either the required class or any super-class declared variable.

Which also helps in the creation and use of abstract classes for method sharing (polymorphic methods).

Is that right?

Thanks,
1DMF

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
Yes, I think that sounds right. So you can

Code:
public void doSomething(ClassA a){
...
}
Code:
b = new ClassB();
doSomething(b);
But not the other way around

-----------------------------------------
I cannot be bought. Find leasing information at
 
Thanks Jaxtell,

This suitablilty / polymorphism is certainly tough to get your head round, especially as you can declare a vairable as a super-class type, then assign it to newly created instance of the sub-class, which actaully creates and instance of the sub-class, but only the super-class methods and instance variables are accessible.

I.E.

Code:
ClassA myclass = new ClassB();

If I understand correctly myclass now references an object instance of ClassB, but will only behave like an object of ClassA and so no methods or instance attibutes of ClassB are accessible.

It behaves in this manner to enable 'suitability' and 'polymorphism'.

Have I got it?







"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
Vocabulary is certainly not my strong point. I'll include a rough example. BTW, during a webinar the other day they mentioned a book called "Thinking In Java" as a entry level java book. You can download it for free as a PDF. I read a bit of it and although the version I was reading was old, it was straight forward and concise.

Anyway, here is some code to help demonstrate inheritance/polymorphism:

Code:
[axtell@Axtell4 ~]$ cat Car.java
public class Car{

public Car(){
}

public void drive(){
System.out.println("Driving");
}

}
[axtell@Axtell4 ~]$ cat Ford.java
public class Ford extends Car{

public Ford(){
}

public void doFordThing(){
System.out.println("Doing Ford Thing");
}
}
[axtell@Axtell4 ~]$ cat Volvo.java
public class Volvo extends Car{

public Volvo(){
}

public void goFast(){
System.out.println("Going Fast");
}


public static void main(String args[]){
Car ford = new Ford();
Car v1 = new Volvo();
Volvo v2 = null;
try{
v2 = (Volvo)new Car();
}catch (Exception e){
e.printStackTrace();
}
ford.drive();
((Ford)ford).doFordThing(); //needed to be cast to Ford to work
try{
((Volvo)ford).goFast();
}catch(Exception e){
e.printStackTrace();
}
//v1.goFast();  //won't compile, no goFast() method for Car

((Volvo)v1).goFast();
try{
v2.goFast();
}catch (Exception e){
e.printStackTrace();
}

}
}

[axtell@Axtell4 ~]$ java Volvo
java.lang.ClassCastException: Car cannot be cast to Volvo
   at Volvo.main(Volvo.java:16)
Driving
Doing Ford Thing
java.lang.ClassCastException: Ford cannot be cast to Volvo
   at Volvo.main(Volvo.java:23)
Going Fast
java.lang.NullPointerException
   at Volvo.main(Volvo.java:31)
[axtell@Axtell4 ~]$

-----------------------------------------
I cannot be bought. Find leasing information at
 
So you can cast a super-class declared variable which points to an instance of a sub-class in order to gain access to the sub-class protocol.

Does casting only work in the same direction as polymorphism.

Could you do the following?
Code:
Car myCar = new Car();

((Ford)myCar).doFordThing();



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
Casting can work in both directions. I think you can cast any non primitive up to an Object or anywhere in between. Up is pretty easy. Its casting down that you have to watch out for class cast exceptions. If you cast further than the object, like casting a Car (that really is a Car) to a Volvo, you'll get an error.

No, you can't do that. You'll get a class cast exception, just like line 23 of my Volvo class example. It should be pretty easy to set up an environment to test code bits like that. I don't actually remember most of this stuff. I just try it and find out what happens.

-----------------------------------------
I cannot be bought. Find leasing information at
 
Casting is only done in one direction: a more abstract type is converted (back) to something more concret.

But that casted thing has to be a hidden Ford in the first place, to be converted back from car to Ford. You can't magically create a Ford from a car, which was never anything more than a car. Often, the more concrete type has additional attributes - where would they come from?

In the other direction you don't need something like casting. If you need a car, you may allways take a volvo, since a volvo is a car.

don't visit my homepage:
 
It should be pretty easy to set up an environment to test code bits like that. I don't actually remember most of this stuff. I just try it and find out what happens.
unfortunately due to a bug in the IDE we are provided, it allows access to method protocols in sub-classes which shouldn't be accessible!.

Casting is only done in one direction: a more abstract type is converted (back) to something more concret.
Thanks stefanwagner, I thought that was the case, I did try a similar expression and my IDE did give a casting error.

I can understand the requirement for suitability and polymorphism, but I still don't understand why you would declare a variable of a certain class type and then instatiate an object of a sub-class.

If you are going to create an instance of an object why would you not reference it with the correctly declared variable type?

Seeings as the instance can be passed back to its super-classes as a formal argument to any methods declared as requiring a variable of any super-class type.

I'm assuming if you create an instance of an object, you are doing so because you want to access that specific classes protocol. Without casting this cannot be done.

If it inherited the other way you might as well declare every variable as Object, but as you don't inherit any sub-class protocols, it seems odd that you would want to declare and initialise an object in this manner.

Would the folowing be perfectly acceptable?
Code:
Object myCar = new Ford();
((Ford)myCar).doFordThing();










"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
Don't you think you're getting too much theory with litle hands-on? Anyway, an example for you, because the last code makes no sense for me

Code:
Car oCar = null;

if (confParamenter = 1)
 oCar = new Ford();
else
 oCar = new Seat();

//whatever you need to do with the car

Cheers,
Dian
 
Don't you think you're getting too much theory with litle hands-on? Anyway, an example for you, because the last code makes no sense for me
Perhaps, but I am getting hands on experience, with activities and of course the actual course assigments.

But I have deliberatly not posted any of that or used any of the the same classes used in the course.

This forum has strict rules on posting assignment/course code, and I don't want to fall foul of them.

But out of interest I tried the code
Code:
Object myCar = new Ford();
((Ford)myCar).doFordThing();
Using the classes in the course, and it works fine, so unless the reason it is working is due to the bug in the IDE, I have to assume that it is a perfectly legal expression.

Dian, I don't understand your example, a seat is not a car, it is part of a car, and I thought all sub-classes have to be everything the super-class is , not part of it.

does that mean the class Car, doesn't do very much, as a seat would share very little in common with a steering wheel, what possible message protocols would it share?

Why would you create a seat object as a Car, because then you cannot access its message protocol and so cannot turn the steering wheel.

Only objects created as class SteeringWheel, can run message send of turnSteeringWheel.

Unless cast is then done against them as per my example to allow access to the message protocol.

hmm, I've got a lot more to learn before this makes sense, that's for sure!








"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
*ROFL* Seat is a european car brand line Citroen or Audi *ROFL* I guess I should have used a Chevrolet :)

Your code will work, of course, but why declaring and Object and cast it when you want to use a Car?

Cheers,
Dian
 
OMG - so funny! yes , I know SEAT, but you might as well say VW , as that's who owns them isn't it?

Your code will work, of course, but why declaring and Object and cast it when you want to use a Car?
exactly my point, I don't understand why it allows you to do something , that doesn't make sense to do, I assume this is a by product of the hierarchy / suitability functionality, but in a real world app, you wouldn't declare it as merley an object and then cast to access the message protocol of the instantiated instance.

However the confusion over SEAT vs seat does confuse me in the sense...

How would you define a car seat and car steering wheel and where in the class hierarchy would Car reside as opposed to Seat and SteeringWheel

Would a Car object just be collection of other class objects?

By the way we haven't studied collections yet, so perhaps when we do things will become a little clearer.



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
Btw, using a cast generally involves a poor OO design, but it's useful to solve a lot of situations when the correct sollution is too risky or has a very high impact

Cheers,
Dian
 
Unfortunately OO design is not covered in this particular course, which is why I will probably have more questions than answers by the end of it!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
How would you define a car seat and car steering wheel and where in the class hierarchy would Car reside as opposed to Seat and SteeringWheel
You can't answer that question without knowing, what purpose the software has. Is it a 3d-racing-game or a webshop for carparts and cars? If connected to each other, a seat would most probably be modeled as an attribute of a car, maybe as a collection of seats in a specific car.

Did you already learn about swing? If you have a JPanel, you can define a layout, and then add elements to the JPanel. It might be a JButton, JLabel, JTextField, another JPanel and so on - the common minimum those elements need to have, is, that they must be a JComponent to be added to a JPanel.

They all inherit from JComponent, and this JComponent contains the methods which are needed to do the layout: getMinimumSize, getPreferredSize and so on.

A type definition is a collection of methods which might be performed for a special type and define therefore, how to interact with something. If you write a method, you will try to allow a wide range of parameters, so you can reuse that method in many cases, and don't need to write a new method for every similar type. That would be a reason to declare a variable as abstract as possible.
Code:
JComponent jc = new JButton ("Exit");
jpanel.add (jc);
Here you couldn't use Object, which is the most abstract type, because Object is too abstract - you can't add every object to a JPanel.
But you won't see such an assignment often, because you often like to do more JButton-specific things to a JButton.

Therefore you can see from the declaration, how a variable will be later used - specific, or in a more abstract way.

don't visit my homepage:
 
Btw, using a cast generally involves a poor OO design
I assume that excludes primative & String types?

As casting in conjunction with the Integer.parseInt() & String.valueOf() class methods would be acceptable?

Did you already learn about swing?
Not that i'm aware of, and I have only just finsihed Unti 6 out of 14, so i'm sure I've got a whole lot more to learn before I'm done!

I really apreciate the input you guys have given , it has helped me better understand what I have already learnt as well as show where I am still lacking to fully appreciate everything that is going on.

At least I think I grasp the concepts currently being taught, so I guess that's a good sign :)

However currently understanding what concrete classes, abstract classes, interfaces and variable types are, doesn't give me enough to apply it to application development.

This is only a 6 month course in a two year qualification, (not specifically in Java), so I can't expect too much I guess, hey it's quite a lot to take in just learning the basics!

so respect to you guys & gals who do this for a living!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
Well we've been taught to use String.valueOf and Integer.parseInt , which converts (casts) from one type to another.

Is this not the case?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
When you "cast" you don't change anything on the target object, it remains exactly the same. When you "convert", you create a new object with the data from the original one

Cheers,
Dian
 
how can that be? If you don't create a new type be it object or primitive how can it hold the new value?

if you cast a double to a long, you are changing the data aren't you?, the result of the 'conversion' has to be stored somewhere doesn't it? for you to then use it.

When you cast from double to int, it drops off the decimal place and the trailing fractions doesn't it?

Which is altering its value and so is 'converting' it to something else.

Sorry , I'm confused with your answer :-(





"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Google Rank Extractor -> PERL v1.5 beta (FusionCharts)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top