aspose file tools*
The moose likes Java in General and the fly likes Interface or inheritance to ensure a base class Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Interface or inheritance to ensure a base class" Watch "Interface or inheritance to ensure a base class" New topic
Author

Interface or inheritance to ensure a base class

Stuart Gray
Ranch Hand

Joined: Apr 21, 2005
Posts: 410
I'm writing some code to create a Swing 'wizard' type component. I have an interface called WizardPage, which represents the features of an individual page, such as getNextPage(), getPrevPage(), etc. I have a WizardController class that manages a list of WizardPages and selects the next one to show.

My problem is that each of the WizardPages needs to be a subclass of JComponent, so that they can be added to a dialog. If I get a list of WizardPages from the WizardController, I will have to cast from WizardPage to JComponent, which seems messy.

My question is basically this: how can I guarantee that any returned pages are both a subclass of JComponent, and implement the WizardPage? The solution I have is to write a DefaultWizardPage class like this:

...and then deal only with those, not with the WizardPage interface. But it seems strange to write the WizardPage interface and then only use it once.
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12789
    
    5
How about making DefaultWizardPage abstract? That would let you define default method implementations that could be overridden for special purposes.
Bill
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Sounds to me like you've discovered one of the inherent flaws of concrete inheritance, and now you're looking for the optimal workaround. Sadly, swing is heavily reliant on behaviour inheritance, which means that the optimal workaround is, at the very least, extremely laborious (automation would be a great project). Since most swing APIs have violated the rule "declare all classes final", "declare all constructors private" and "declare all public methods on an interface", you cannot use a supertype contract, so you'll have to write one yourself.

For example, given

...you can "isolate the brokenness" with:

Now you might say, "where is my type safety?". That is, your reference of type the.fixed.X cannot be used as a the.broken.X. You have three alternatives, in order from least to most laborious:
1) You can write an adapter(GoF)

2) You apply the same principle that is used above to all types, including where method parameters are used. That is, where a the.broken.X is expected, write a new contract (interface) that accepts a the.fixed.X and delegates to the underlying broken implementation - everything appears "nice" and it gives you hope that one day it will be fixed, or at least, partially (a good start would be to put all public methods on interfaces).

3) Change your dependency so that you don't depend on poorly written APIs (such as the J2SE API Specification). Since the J2SE API Specification has a bi-directional dependency relationship on the language specification (JLS), you'd also have to remove that dependency. Before you know it, you're rewriting a language and API spec. that can run on a JVM, .NET CLR or anything theoretically (since the bytecode spec. is left to implementations). Hey wait a minute, that's what I'm doing right now!!

Good luck and don't believe the hype.

Disclaimer: No code samples have been checked for integrity, and may certainly contain errors.
[ August 21, 2005: Message edited by: Tony Morris ]

Tony Morris
Java Q&A (FAQ, Trivia)
Stuart Gray
Ranch Hand

Joined: Apr 21, 2005
Posts: 410
Thanks for your replies. William, I considered making the class abstract but wondered if there was a 'better' way. Tony, you managed to state my precise problem in a very eloquent way - thank you. I can't quite get my head around the solutions you proposed at this time of the morning but will definitely try to implement one of them later.

Thanks again guys
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Good to hear. I agree though, it does require some serious objective thought; most (claimed) experts can't even manage to get their head around it! The primary objective is to identify your problem - be warned, I have only paraphrased it - it goes much deeper and can be traced all the way back to requirements analysis. It's difficult to abandon preconception in the conditions that we live in today. I own a television, but only because my girlfriend forces me to as a compromise

<edit>
Also, be warned, ignorance is bliss, it truly is. Stepping out of the protection of orthodoxical beliefs has a high cost, particularly in an egotistic industry such as the one that we exist in; I'm sure Galileo or Copernicus would agree there. If you wish to think once, think twice, and so on - there is no going back.
</edit>
[ August 21, 2005: Message edited by: Tony Morris ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Stuart Gray:
I'm writing some code to create a Swing 'wizard' type component. I have an interface called WizardPage, which represents the features of an individual page, such as getNextPage(), getPrevPage(), etc. I have a WizardController class that manages a list of WizardPages and selects the next one to show.


Interesting - we are working with such a homegrown solution for some time now, too! (We are also working on making it open source, but it probably will be some more time before it will be online...)

My problem is that each of the WizardPages needs to be a subclass of JComponent, so that they can be added to a dialog. If I get a list of WizardPages from the WizardController, I will have to cast from WizardPage to JComponent, which seems messy.


Yes, that would be messy.

The solution we choose is to have WizardPage *not* be the JComponent, but to have a getContent() method that returns the JComponent for the page. It is working very well.

Tony, this is one of the examples where implementation inheritance actually provided value for us. A WizardPage has methods such as isHelpAvailable(), and AbstractWizardPage provides a default implementation that returns false. Subclasses are free to override it. I'd be very interested in your opinion on why you think about this as problematic, and what you would do instead.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
For all cases where implementation inheritance is used, the flaws can be highlighted and a better alternative provided. The best refutation to concrete inheritance that currently exists is "saves typing", and that exists merely at a source level in a Java context. One might argue that this argument is easily invalidated. A good programming language would not suffer from this problem, such as the one that I am currently working on (ok I lied - I just don't have the time at the moment).

I strongly encourage you to think about it some more; do you not think I've heard your argument before? I promise you, I have countless times.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Tony Morris:
I strongly encourage you to think about it some more; do you not think I've heard your argument before? I promise you, I have countless times.


I promise you, I've read a lot about favoring composition over inheritance, and I've thought *and experimented* a lot. And in my experience there are a lot of cases where the complexity of using a more flexible approach than inheritance simly isn't worth it. Maybe there are languages in which there are better approaches, and I'd certainly like to learn about them should someone be nice enough to point me at them, but it's unlikely that I will get paid using them in the near future. And frankly, I have some more important gripes about Java than the use of implementation inheritance...
Stuart Gray
Ranch Hand

Joined: Apr 21, 2005
Posts: 410
This is an interesting discussion. It seems that the idea of using an abstract base class as suggested by William would be the easiest to implement, and if only for that reason, IMHO it therefore has value in some situations.

I'm not sure, but from my understanding the idea suggested by Tony in his first post is not that different from what Ilja is suggesting - particularly the bit about the getComponent method to retrieve the Swing component. This is what Tony is talking about when he says "hiding the brokenness", isn't it?

OTOH, I haven't had time to work on the code yet since I first posted, so I don't know which approach will work best in my situation. The project is partially to learn some new skills, so certainly different patterns and concepts are up there on my to-do list.
[ August 23, 2005: Message edited by: Stuart Gray ]
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
"easiest to implement" meaning "saves typing" or do you mean "easiest to implement" because you find it difficult to conceptualise any other way? In both cases, the argument is moot - it's actually easier to conceptualise once you train your mind (typically, through practice); the only reason the fallacy has reached critical mass is because of texts, documentation, marketing literature, etc. that typically has a financial primary agenda. Abandon preconception and enjoy enlightenment. It's recognising whether you are actually thinking objectively or doing the sheep thing that is the tough part. Always ask yourself "why?" and then ask yourself why you think why.

Though the analogy is imperfect, it is akin in some ways to the renunciation by Galileo that the Earth is the centre of the universe. Critical mass believed in doctrine created by the Catholic Church with some other primary agenda. There are thousands of examples of this social structure that I'm sure you (any layman) and I would agree on immediately; don't rule out that there are others. Is the sky blue or does it appear blue? Does beer taste like piss, or is it a taste that requires "training"? Does the Earth sit in the centre of the universe? Any 15th century Greek would answer, "Of course it does! Only a fool thinks otherwise!" I like being a fool despite the rocks that are hurled at me. I'll leave the argument of whether religious agendas and financial agendas are really the same thing up to those who care about it more than I.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
I don't know what favouring composition over inheritance has to do with anything, other than the same people who argue about it can tell that something is wrong, but they can't quite figure it out.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Tony Morris:
"easiest to implement" meaning "saves typing" or do you mean "easiest to implement" because you find it difficult to conceptualise any other way?


Tony, are you aware of the fact that this is a false dichomoty?
Stuart Gray
Ranch Hand

Joined: Apr 21, 2005
Posts: 410
Originally posted by Tony Morris:
"easiest to implement" meaning "saves typing" or do you mean "easiest to implement" because you find it difficult to conceptualise any other way?

I guess I mean it in several ways. Not for saving typing at all. Time is an important consideration. This is just a small project to get (and keep) myself up to speed on a few things I have forgotten before I approach another more significant project. I do find it quite hard to conceptualise this at the moment and, rightly or wrongly, I can not find the time to try right now. Programming is not my profession and the application I am trying will not need to be maintained (because it probably won't be used for anything other than 'lessons learned'). After I have finished i may well try to implement another using different approaches, as a comparative study.


Does beer taste like piss,

Of course not! Piss tastes like beer!
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Only if you assume a context, which I assume you're assuming based on understandably, intuition, but it's not the case.
It's a question, which has been answered.
Would it help if I had suffixed the question with "or some other explanation of your choosing"?
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Tony Morris:

Would it help if I had suffixed the question with "or some other explanation of your choosing"?


To me, it would have sounded more like someone why tries to understand my position than someone why tries to defend his own. Might just be me, though...
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Interface or inheritance to ensure a base class