Results 1 to 3 of 3
- 12-23-2009, 11:01 PM #1
Member
- Join Date
- Dec 2009
- Posts
- 3
- Rep Power
- 0
Usually work with C++, need help replacing multiple inheritance in this case
I usually work with C++ (I would call myself "experienced" with it), and I'm just starting out with Java. To start out, I'm working on porting a set of simple classes that I use for making quick 2D games with, but I can't figure out how to replace the multiple inheritance that I used in the C++ version's event handling system. Here's the basic layout of my code:
Java Code://class from which all GuiObjects are derived public class GuiObject { //overridden by inheriting object, called when any event pertaining to the Gui fires protected void classEvent(...) { } } //an example interface, which defines certain event handler functions public interface GuiMouseButtonEvent { //overrides the classevent, and calls on this handlers functions protected void classEvent(...); //IN C++ I WOULD DEFINE IT HERE protected void OnButtonDown(); protected void OnButtonUp(); ... } public class TestObject extends GuiObject implements GuiMouseButtonEvent { protected void classEvent(...) { //PROBLEM!! --> THE USER SHOULD NOT HAVE TO DEFINE THIS, WHERE / HOW SHOULD I DEFINE IT? } protected void OnButtonDown() { } protected OnButtonUp() { } }
The problem is that the GuiObject class should not be aware of any of the event interfaces. Where do I implement each interface's code for determining what handlers(s) to call on given the event? Given that the user should not see that code, and the GuiObject class cannot be aware of each event's implementation?
I don't necessarily need to keep it this way, so if I'm simply taking the wrong approach altogether, then please let me know, thanks.
-Stravant
- 12-24-2009, 06:55 AM #2
yes, thats a good example of why multiple inheritence can be a good thing, but i digress, that discussion is long dead for why Java doesn't do it.
I sometimes create intermediate Glue objects that extend my parent class and provide default implementations of the methods. In your case,
Java Code:public class MyDefaultMouseButtonEvent extends GuiObject implements GuiMouseButtonEvent { protected void classEvent(...) { // implement it here } public class TestObject extends MyDefaultMouseButtonEvent //implements GuiMouseButtonEvent {
and I have interfaces A, B, C, and I want some classes to implement {A}, {B}, {C}, {A,B}, {B,C}, {A,C}, {A,B,C}, then yes, I need to make like 7 of these glue classes, where yes, possibly I would have to implement the method bodies more than once. But in this case I work around this by creating a static utility method, or some other spot for which I can have the method in the glue class(es) that needss to be there just to satisfy the implementation of the interface requirement,
Java Code:GuiMouseButtonEvent { protected void classEvent(...) { // implement it here GUIUtils.classEvent(); // our function just calls our single defined logic somewhere else }
Another idea, would it be possible to reverse the interface / class. what does GUIDObject contain ?
In some cases if the base class is really behaving more like a 'marker', then I have been able to make the 'interface classeses and the classes interfaces'.
For example, instead of having BaseObject class that I extend and interfaces A, B, C,
if I create ClassA and implement some BaseInterface instead.
Oh, and another thing that comes in handy sometimes, which I guess is closer to multiple inheritence, is containership, where your class defines a member (field) that is an instance of the other class that used to be inheriting from.
For example,
Java Code:public class GuiMouseButtonEvent { protected void classEvent(...) { } protected void OnButtonDown() { } protected OnButtonUp() { } } public class TestObject extends GuiObject { GuiMouseButtonEvent mymouseListenerInstance; }
Sometimes the best solution is to not try to 1:1 map the C++ object, but to try to use the Java-esq facilities that already exist for solving a problem. For example, in a JButton (a component in the Swing API), it is sometimes convenient to have it's event handler implemented inline by an anonymous inner class
Java Code:JButton okButton = new JButton("OK"); okButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { // here the logic of when the button would be pressed, can access things in the parent java class, or propertis in this code block parent if they are final. } });
but in a more practical sense, when there would be more than one button using things, and in your case, a mouse listener,
Java Code:MouseListener myMouseListener = new MouseAdapter() { // MouseAdapter is a built-in thing that just implements the MouseListener interface, // here you would provide method implementations for the event things you care about. } JButton okButton = new JButton("OK"); okButton.addMouseListener(myMouseListener); JButton cancelButton = new JButton("Cancel"); cancelButton.addMouseListener(myMouseListener);
- 12-24-2009, 07:41 PM #3
Member
- Join Date
- Dec 2009
- Posts
- 3
- Rep Power
- 0
"Another idea, would it be possible to reverse the interface / class. what does GUIDObject contain ?"
Interesting idea, but that would be even more so of a problem. GuiObject itself is a fairly heavy object (should have described what else it has in the first place, sorry). It contains a parent-child object hierarchy, and a bunch of layout and rendering functionality, events are by far the smallest part of the implementation done in the class.
"it is sometimes convenient to have it's event handler implemented inline by an anonymous inner class"
While I was reading what you had to say about that it finally clicked a way I could implement that, I was having trouble figuring how exactly that worked internally before.
Here's the new idea, it's looking like it should work:
Java Code:public class GuiEventH { protected void Implementation(...) { //overridden by each type of event handler, calls handlers of that event class } } public class GuiObject { //handlers private GuiEventH[] handlers; //array for now protected void HandleEvent(...) { //default behavior is to call on handlers for (GuiEventH handler : handlers) { hander.Implimentation(...); } } protected void AddHandler(GuiEventH h) { whatever_the_table_insert_function_is(handlers, h); } } public class GuiMouseButtonEventH() { protected void Implementation(... e) { if (e instanceof buttonevent) { OnClick(); } } void OnClick() { } } public class TestButton extends GuiObject { TestButton() { AddHandler(new GuiMouseButtonEventH() { void OnClick() { Remove(); //remove self, easy to test } }) } }
Similar Threads
-
subclasses and inheritance - how's it all work?
By 711groove in forum New To JavaReplies: 14Last Post: 12-18-2009, 10:04 AM -
SashForm doesn't seem to work in this case
By Rodrigo Braz in forum SWT / JFaceReplies: 0Last Post: 03-22-2009, 11:39 AM -
multiple inheritance in java
By pawanspace in forum New To JavaReplies: 2Last Post: 12-31-2007, 05:08 AM -
Multiple Inheritance
By mew in forum New To JavaReplies: 1Last Post: 12-01-2007, 11:04 PM -
Multiple Inheritance in java
By paty in forum New To JavaReplies: 4Last Post: 08-02-2007, 03:25 PM
Bookmarks