开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜