• Post Reply Bookmark Topic Watch Topic
  • New Topic

Abstract classes vs polymorphism  RSS feed

 
justin mcsporran
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
The code below was presented in a course I went as problematic, because the calculations (the calc* methods) to determine fuel efficiency for the different types of vehicle are likely to be quite different.
The solution given was to use abstract calc* methods in the Vehicle super class and implement them in the Truck and RiverBarge sub-classes.
However, I would have thought that abstract methods in Vehicle weren't 100% necessary, since the run-time type of variable v (in FuelNeedsReport) would have dictated the use of the correct (overridden) calc* methods for the various vehicle types retrieved from Company.
I seem to remember this as being a result of the "virtual method invocation" polymorphism feature in java.
Please tell me what I'm missing. Thanks, J.
 
rom chatterjee
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think what was being suggested was that you have a generic Vehicle. For all Vehicle objects there must be these calc* methods, although the specific implemetation is unknown.
By declaring the methods in Vehicle you are forcing all types (subclasses) of Vehicle to implement these methods. Now anyone that works with a vehicle can be safe in the knowledge that all Vehicles (barges, trucks, etc) have this behaviour.
If you did not declare them a Truck may still have the calc* methods but theres no guarantee.
Also youve got no benefit from the polymorphic nature of objects, as you couldnt call v.calcXXX(), if calcXXX() is not a method of Vehicle.
Example:
Vehicle v = new Barge("barge")
b.calcXXX();
Wont work as calcXXX is not a method of Vehicle. You can create v as a Barge because a Barge is a Vehicle. So b instanceof Vehicle = true. To use the barge method you would have to place the v in a Barge object:
Barge b = (Barge) v; // pointless
 
Joel McNary
Bartender
Posts: 1840
Eclipse IDE Java Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Indeed. Polymorphism does not imply a weakly typed language. Compare:

This is an Objective-C method which takes a Parameter of type id (the equivalent of a Java Object) and runs the "dance" method of the object. This will compile and work, even though there is no guarantee that the aParameter object implements the dance method. If it doesn't, you will receive a runtime error. Compare this with the equivalent* Java code:

This will get a compile-time error because Object does not have a dance method. If you defined an abstract class Dancer** which had a dance method, you could change the parameter type to Dancer and everything would be copacetic. But the key is that Dancer would have to have the abstract method defined or else it would be in the same boat as Object in the above example--a compile-time error.
Lesson learned:
It's the compile-time type of a variable that defines what an object can do, but the run-time type that determines how it does it.
--------
* OK, the actual equivalent code would be:

but that's from an implementation point of view, not a coder's point of view
----------
** Actually, Dancer would best be served as an interface instead of an abstract class. That way, if you had a Human Class, a Bumblebee class, and a Warthog class (each of which inherited from the abstract Animal class), your Human and bumblebee class could implement the Dancer interface since both of them can dance, while the Warthog would be unable to dance. (At least, I've never seen a dancing warthog ) You could then pass both Humans and Bumblebees to the above method, since both of them are Dancers.
[ May 14, 2003: Message edited by: Joel McNary ]
 
justin mcsporran
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Rom,
I agree absolutely that the lack of calc* methods in the super class would mean that virtual method invocation wouldn't amount to much (the compiler would probably complain about unresolvable symbols in the super class).
However, I was assuming that the Vehicle class in this example would in fact have calc* methods to be overridden in the subclasses Truck and RiverBarge.
In this case, the only argument I can see for making the calc* methods abstract in the Vehicle class would be if there is no logical/"real world" default implementation for such methods, given the kind of class it is.
Is that fair, or am I still not getting it?
Thanks,
Justin
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!