This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I have a bunch of classes (I didn't create) that all have the same methods, like setPosition and draw. I created a class that allows mixed groups of them that I can setPosition and draw them as an aggregate. First I had to create an interface and then new classes that extended these separate classes and implemented the interface. I was going great until I found that one class implemented the draw method differently (all the other classes have void methods, this one returns a value). So I know I can't override a method with one that has a different return type. I'm wondering what clever people do in this situation.
My thought was to change the draw method to drawMe in my interface and in each of the new classes I made that implement my interface explicitly add a drawMe method that just calls super.draw(). It's just then I have to remember that my classes use drawMe and classes that are part of the original package use draw, unless I make my own version of every one of them. Is there a better way to go?
Probably several; but if it was me, and
1. I'm not expecting a lot of these "exception" classes.
2. I don't actually need the value that is being returned.
I think I'd probably just create a wrapper class that decorates the "exception" class to implement the interface (and specifically its draw() method) as required.
But, like I say, it's just one possibility.
Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
My initial instinct would be to go with Winston's approach as well.
I'd consider this a form of the Adapter pattern, which you can use whenever you have a class that provides the services you need but doesn't provide it using the interface you need. You create a wrapper class that delegates to the wrapped class, and carries out any translation needed between the two interfaces. It sounds like in this case the only translation needed is "ignore the return value" (assuming, as Winston says, you don't actually need that return value for anything).
Joined: Oct 10, 2011
Thanks for the replies. I've looked at the link about the adapter pattern. There is something I am not quite getting.
I have a class Table. It has a method draw which returns the value Point. This is how I got started.
My interface, leaving everything out but the draw method
works fine for images and text, as they have a draw method that doesn't return anything.
My class creating a Table DrawObject
TableObject.java: draw(Page) in TableObject cannot override draw(Page) in Table; attempting to use incompatible return type
found : void
public void draw(Page page)
But now I am stuck, as I don't see how to work my way around the fact I can't override the method of the class I am extending. I am not going to use the return value, at least not here. I'm just not catching on to how to ignore it.
FYI, my original idea was to have something like this
which works except for my TableObject as I am not getting how to write the adapter that makes draw work other than creating a new method in my interface (drawMe) and using that instead. Which means changing all the other xxxObjects to have a drawMe also. Could you describe a little bit more about what the adapter would contain?
Jon Swanson wrote:But now I am stuck, as I don't see how to work my way around the fact I can't override the method of the class I am extending. I am not going to use the return value, at least not here. I'm just not catching on to how to ignore it.
If you re-read my post, you'll notice that I said "create a wrapper class". What you're trying to do is create an extension, and that probably won't work.
Try something like:
Joined: Oct 10, 2011
OK, what was confusing me was I had it in my head to try to keep my original class and add a wrapper/adapter rather than replace it. Am I correct the other change is that when I was extending the original Table, I didn't explicitly define most of the methods in my interface, as they are defined in the original Table class. With the wrapper, I will need to explicitly implement each of these methods? Though these will just be things like:
I only put the methods in my interface that DrawBlock needs. For the other methods I would use xxxObject.yyy() where yyy is a method in xxx. So what I am thinking is that either TableObject has to be unique and I include another method getTable() so I can do tableObject.getTable.yyy() or implement all the Table methods in TableObject. I presumably could have the constructor of TableObject create the Table.