I'll spare everybody the gory details, but as you can imagine, the class Car extends Vehicle, and lets just say the method drive() just prints out either "Car Drive" or "Vehicle Drive" The ouput of the little program is: "Vehicle Drive" "Car Drive" "Car Drive" See I don't get that, it just isn't right in my head. That one line that reads v = c. The way I try to remember it, is ok, "c" is coverted to a "v" so that it can fit into a "v." "c" CAN be converted to a "v" because in actuality "c" is just a "v" with some add-ons. Ok, but then the line v = c, should actually give me a vehicle that has only vehicle stuff, but apparently that is not the case. So how should I really be thinking about this? Please help, I don't know why I can't see this. It just doesn't make sense to me that a pet can be turned into a cat. I mean, if Pet p = new Pet(); Cat c = new Cat(); why should p = c work, unless c is converted to a Pet and all the "Cat" information is taken away. [ April 21, 2003: Message edited by: Wilson Mui ]
The way I think about this is that Vehicle can point to a Car. Now that the Vehicle is pointing to a car and Vehicle contains a method named drive() then its possible for Vehicle to point to car's drive() method. But if Vehicle doesnt contains a drive() method then it would be wrong. This is because Vehicle has no way of knowing which methods (apart from the ones of inherited from Vehicle) does the Car class has. So a superclass can point to subclass's method provided they are know (inherited) to the superclass.
Maybe this type of thinking will help: This is one of the great advantages of OOD. If you were not able to make a generalized class and extend it, then you would have to create all these different method names that did essentially the same thing: You would have to have a "carDrive()", "truckDrive", "segwayDrive", etc. With OO, no matter what type of Vehicle that is on the other end of that Vehicle reference, all you have to do is call the drive() method, and that subclass of Vehicle knows what to do. So, for example, if you didn't know there was a Car on the other end of that Vehicle reference, it wouldn't have mattered: The Car still knew how to drive itself. To address some more concrete issues:
That one line that reads v = c. The way I try to remember it, is ok, "c" is coverted to a "v" so that it can fit into a "v." "c" CAN be converted to a "v" because in actuality "c" is just a "v" with some add-ons.
Here it seems like you are thinking of object references as if they were primitive data types. What happens in the "v = c" line is that the address of the object that c is pointing to is being given to v, so now they point to the same object. "c" is not being converted to a "v", "c" is actually the same as it was before the assignment; the difference is, "v" is now pointing to what "c" is pointing to: The Car. This is like what Anupam was saying. [ April 21, 2003: Message edited by: Larry Jones ]
This is an example of polymorphism.The actual object type, not the reference type, is used to determine which drive method to use. This happens at runtime. Thinking in terms of 'pointing' is not so fruitful in java. I hope I am right. Rattan
ok, I am starting to see it in a different light. but it will take some time for me to get rid of the old understanding. So in this case, would making a Car = Vehicle work? I was looking through the API, and from what I can tell it would work. Because you can up cast or down cast as long as one extends the other. But in this case, after I declare that Car c = v (which is a Vehicle), what happens to the drive() method, who's drive method do I use? Just from intuition I would say the Vehicle's drive method. Also another way I was reading up to think of it is, think of an object, and you can have many different references pointing to an object, you can have a Object reference, or a PieceOfMetal reference, or a Vehicle reference, or a Car reference. All of those things can be pointing to the Car, but the Object, the actual Object will always be a car, with all it's bells and whistles. So even though in some cases, a scrapyard might think of things in terms of PieceofMetal, when it rolls in the junkyard, it will always still be a car. But does anybody have an answer for my other question, and then of course how I should be thinking about this?
I beleive Car c=v should not work. Car is a vehicle so you can assign it to a vehicle reference. But a vehicle is not a car so you can't assign a vehicle to a car reference. This is how I think. As said in another post object references and primitive references work differently. Rattan
Hi Willam Well no Car c = v; won't work. Firstly the cast is missing had it been Car c = (Car)v; it would have compiled. But I guess that it would still throw a Runtime ClassCastException. This would be because Vehicle is a superclass and if it contains a reference to a class that is covertible to Car it's OK. But in this case Vehicle is not converible to Car. But the fact that Vehicle is not converible to Car is not known at compile time the compiler leaves it to its fate and in case an error occurs it reports an exception. I think I am correct but do please correct me if I am not. [ April 22, 2003: Message edited by: Anupam Sinha ] [ April 22, 2003: Message edited by: Anupam Sinha ]
yes you are both correct. I think my mind was just not set right, between being able to cast an erroneous object and the inheritance thing...I think I have it straight, but I'll know when I have to answer another question. Thanks everybody