Using inheritance to alter a superclass's interface
I come from a web-development background. I've been playing around with a bit of Java recently and have come across the following issue that seems to stem from the strict interfaces and data-typing which are more part of Java than they are of PHP.
I am using an existing physics engine (Phys2D) to develop a game of sorts. This physics engine has Body
objects managed by a World
, and have various forces applied to them as the world is stepped. It is important for the AI in the game that the bodies have colours (so that they can be sensed), but this is not supported by the physics engine, so I've created a subclass, and extended the Body
class to include this - http://pastebin.com/1nLYWg3w. Now when I create these Body
instances, I can get them back from the World
and get th开发者_如何学编程eir colours.
However, Netbeans is saying that it
cannot find symbol
symbol: method getColour()
location: class net.phys2d.raw.Body
because the Body
objects returned by the physics engine interface do not contain this method. I know that, at runtime, all the Body
objects that are passed to the World
will actually be objects of ColouredBody
type, and so will have this method defined in their interfaces.
How can I attach colours to the Body
objects and not produce scary underscores and warnings? I understand that I can alter Phys2D itself but, potential licensing restrictions aside (the licence says that you can do this with Phys2D), I am told that this is bad practice.
If you know at runtime that all your Body
objects are actually ColouredBody
, then you can cast those objects to ColouredBody
and call getColour
:
Body body = ...;
ColouredBody colouredBody = (ColouredBody) body;
colouredBody.getColour();
Actually, I'd say it would be perfectly good design to add the colour property to the Body class of the engine itself.
If you can't do that or don't want to, all you have to do is cast the Body
instances to ColouredBody
before using them:
((ColouredBody)body).getColour();
This tells the compiler "I know that body
is really an instance of ColouredBody
, so let me use it like one" - but if it turns out not to be at any time, you will get a ClassCastException
.
You can cast to the concrete type:
ColouredBody cbody = (ColouredBody) body;
preferably, just to avoid problems, you can check whether it's really true:
if (body instanceof ColouredBody) {..}
Note that downcasting (from more general to more concrete class) is usually considered a bad practice.
If it is possible, you can try to extend World
with ColouredWorld
and override methods that return Body
to return ColouredBody
(and also hold the bodies in the proper collection), but that might be an overkill depending on the complexity.
精彩评论