Java Forum / General / December 2005
javax.swing.ButtonGroup's add method violates implied contract
Kent Paul Dolan - 24 Nov 2005 00:47 GMT Color me picky, but the javax.swing.ButtonGroup's add( AbstractButton b) method, which internally adds the AbstractButton to a Vector<AbstractButton> named "buttons", seems to me to violate the implied invariant contract of java.util.Collection's add(E o) method, see:
.../jdk1.5.0_05/docs/api/java/util/Collection.html#add(E)
in that it doesn't return a boolean "true", or alternately throw an exception, such that a normal return means that the add of the button was indeed successful, the invariant mentioned above.
The javac compiler, of course, will then not let a class derived from ButtonGroup override the add method in a way that does correctly throw such an error when the add to the Vector, or to some parallel Vector used in the extended class, fails.
Am I off in outer space somewhere, or is this really a Sun design error in the ButtonGroup class?
In my case, I'm trying to add a Vector<Boolean> in the class derived from ButtonGroup [which could be better called ExactlyOneButtonSetGroup], named by me AtMostOneButtonSetGroup, paralleling "buttons", so that I can store and reference the state of a button _prior_ to the action that informs me the button just changed to a "selected" state, to see if that was _already_ its state, in the interest of creating a "one or zero" quasi-RadioButton class as recommended in the ButtonGroup JavaDocs, by using an extra, invisible JRadioButton in the ButtonGroup, to which selecting an already selected button will move the selection.
[I'm sure I'm reinventing a rotating object here, and, since this is the second time I've had to do so, a bit surprised this isn't an already provided behavior in some javax.swing class derived from or parallel to ButtonGroup. It seems to be a very common third behavior requirement for stateful toggle buttons besides the ones already provided as checkboxes and radio buttons. The "use an invisible radio button" ploy, while it can be made to work, is a desperate kludge to avoid having a third standard class that does this behavior "right", it seems to me.]
xanthian.
John C. Bollinger - 24 Nov 2005 04:58 GMT > Color me picky, but the javax.swing.ButtonGroup's > add( AbstractButton b) method, which internally adds [quoted text clipped - 8 lines] > the add of the button was indeed successful, the invariant > mentioned above. ButtonGroup does not implement Collection, therefore the contract for Collection.add(Object) is in no way relevant to the form and behavior of ButtonGroup.add(AbstractButton). The fact that internally the method may add the specified button to a Vector is an implementation detail, not relevant to the question. If you nevertheless want to pursue the matter then you should consider the fact that the more specific contract of Vector.add(Object) specifies that that method always returns true and never throws an exception. I really don't see how any of that leaves you cause for complaint.
> The javac compiler, of course, will then not let a class > derived from ButtonGroup override the add method in > a way that does correctly throw such an error when the > add to the Vector, or to some parallel Vector used in > the extended class, fails. I don't see any correctness issue in this situation. Moreover, adding an object to a Vector via add(Object) has no defined failure mode, not even any documented unchecked exception (contrast Collection.add(Object)), so the specific potential failure you describe can't happen anyway if every class correctly adheres to its contracts.
> Am I off in outer space somewhere, or is this really a > Sun design error in the ButtonGroup class? I don't see a design error. I don't even see much of a feature hole because GUI construction is normally a development-time issue; if you don't want a particular button in your group then don't add it -- the matter is completely within your control.
> In my case, I'm trying to add a Vector<Boolean> > in the class derived from ButtonGroup [which could [quoted text clipped - 10 lines] > selecting an already selected button will move the > selection. That would be a very unintuitive GUI element. Button groups just don't usually work that way. The ButtonGroup Javadocs suggest instead using a seperate, normal button that has the effect of clearing the button group (by programmatically selecting the invisible button), which to me seems much more usable. Even that is a bit of a hack as far as I am concerned; button groups aren't *supposed* to be cleared.
> [I'm sure I'm reinventing a rotating object here, and, > since this is the second time I've had to do so, a bit > surprised this isn't an already provided behavior > in some javax.swing class derived from or parallel > to ButtonGroup. As I wrote above, the behavior you describe runs against typical GUI conventions. I'm therefore unsurprised that the functionality has not been codifed into the platform library.
> It seems to be a very common third > behavior requirement for stateful toggle buttons [quoted text clipped - 3 lines] > kludge to avoid having a third standard class that > does this behavior "right", it seems to me.] I don't see this as an issue to do with JCheckBox or JRadioButton at all, but rather with ButtonGroup. The former are used /with/ the latter, but it is the latter (ButtonGroup) that drives the behavior you're talking about. Am I missing something here?
 Signature John Bollinger jobollin@indiana.edu
Kent Paul Dolan - 27 Nov 2005 03:23 GMT > ButtonGroup does not implement Collection, > therefore the contract for Collection.add(Object) > is in no way relevant to the form and behavior of > ButtonGroup.add(AbstractButton). Umm, do you really feel that hairsplitting on the is-a/has-a boundary is a fruitful way to decide if a design is robust? That's language lawyering, not architecting.
> If you nevertheless want to pursue the matter then > you should consider the fact that the more > specific contract of Vector.add(Object) specifies > that that method always returns true and never > throws an exception. That is _really_ frightening. Java, whose "pointerless" design is nevertheless perennially throwing null pointer errors, has designers who think, and embed that thought in design, that their code _cannot_ fail, for something as complex as Vector? Brrrr.
> I really don't see how any of that leaves you > cause for complaint. More than ever, as it eventuates.
> I don't see any correctness issue in this > situation. Moreover, adding an object to a Vector [quoted text clipped - 3 lines] > failure you describe can't happen anyway if every > class correctly adheres to its contracts. I don't share your naive trust in the Java compiler and runtime implementation.
> I don't see a design error. I don't even see much > of a feature hole because GUI construction is > normally a development-time issue; if you don't > want a particular button in your group then don't > add it -- the matter is completely within your > control. What on earth does that have to do with whether adding to a ButtonGroup, which encapsulates an add to a Vector, which _is_ a Collection, exposes the exception that is supposed to be thrown to the client when add() fails?
> That would be a very unintuitive GUI element. What on earth is "unintuitive" about an "at most one" set of buttons?
In my case, I have a feature of a graphical display which can have one of two states, or not appear, so I want exactly "A or B or neither, but not both". I _don't_ want to expend 50% more screen real estate than is necessary to achieve that result.
> Button groups just don't usually work that way. Because, according to its own documentation, ButtonGroup _is_ the implementor of the JRadioButton "exactly one" behavior; the button itself _cannot_ implement that behavior, doing so would violate encapsulation. Thus ButtonGroup "usually", indeed, _always_, behaves as containing a single set of radio buttons.
The "issue", if issue there is, is that the "at most one" behavior is at least as common as the "exactly one" behavior, but there is no "built-in" ButtonGroup-paralleling mechanism to implement this behavior.
> The ButtonGroup Javadocs suggest instead using a > sep[A]rate, normal button that has the effect of > clearing the button group (by programmatically > selecting the invisible button), which to me seems > much more usable. You apparently have screen real-state to give away on a useless button; I don't. You have besides, missed that the "none" button is recommended merely as one of several possible ways to implement that invisible button, but by then you've already spent a visible and distinguished button, making the invisible button completely pointless, and thus that recommendation purely bad advice.
Selecting an already selected button, in the current implementation, triggers the same signal as selecting it when it was unselected, which is an ambiguating design error by Sun. Doing so should either do nothing at all, or, as I'm seeking, clear the button without setting another one. To avoid that ambiguation of the two situations, the client would have to do as I am trying to do (have done, in the case, but without the joy of a better implementation than Sun permits), by recording the prior state so it can be checked whether the new "selection" is merely a redundant click.
> As I wrote above, the behavior you describe runs > against typical GUI conventions. In your apparently limited experience, that might be so. I've been designing GUIs roughly since that was even possible, and there are no such "conventions" known to me.
> Am I missing something here? Sigh. Merely reading comprehension. I was still writing about ButtonGroup, since the _behavior_ is implemented at that level. Somehow, you lost grasp of the discussion along the way when other terms were mentioned. Better luck this time.
xanthian.
John C. Bollinger - 27 Nov 2005 22:09 GMT >>ButtonGroup does not implement Collection, >>therefore the contract for Collection.add(Object) [quoted text clipped - 5 lines] > design is robust? That's language lawyering, not > architecting. I don't see any hair splitting here. On the contrary, I find it odd that you assert that ButtonGroup.add(AbstractButton) should be expected to have behavior governed by that of Collection.add(Object), simply on the basis of /using/ Vector.add(Object) internally. If there is a design error here then I would say that it is in ButtonGroup exposing details of its implementation of add(), not in ButtonGroup.add(AbstractButton)'s similarity or dissimilarity to Collection.add(Object). You are the one who raised the issue of the Collection contract, and thus I think it very relevant to observe that ButtonGroup is not bound by that contract. Furthermore, Vector, which *is* bound by that contract, fulfills it just fine without ever returning false from its add(Object) method or throwing an exception (though it might occasionally throw an Error).
>>If you nevertheless want to pursue the matter then >>you should consider the fact that the more [quoted text clipped - 8 lines] > code _cannot_ fail, for something as complex as > Vector? Brrrr. Certainly one must either discard the idea of Java being pointerless or allow that "NullPointerException" is misnamed, but I don't see how that enters the picture. Classes throw that exception when presented with nulls that they cannot handle, which is always the result of a bug, usually one in the client class.
That Vector has no failure mode specific to it, however, is not so strange. Vectors accept any and all elements, including null, so Vector.add(Object) never fails on account of the argument. One must presume that the method is not buggy, but even if it were, it is not reasonable to expect a defined result if such a bug were triggered. The remaining failure cases involve general VM conditions that are always potential failures for any code; foremost among these is an OutOfMemoryError. Such conditions are rarely, if ever, documented on individual methods because they don't really "belong" specifically to any method.
One certainly /could/ complain that Vector's design makes it difficult to usefully extend the class. I would agree with that. I do not find anything frightening about it, however. I also don't have much complaint with not being able to extend Vector, as I have never seen a good reason to want to do so (present discussion included). It is almost always the case that giving a class a Vector member is more appropriate than making it extend Vector.
>>I don't see any correctness issue in this >>situation. Moreover, adding an object to a Vector [quoted text clipped - 6 lines] > I don't share your naive trust in the Java compiler > and runtime implementation. I don't understand your concern. You ultimately have no alternative *but* to trust the compiler, the runtime implementation, and the platform library. One tests carefully, to be sure, and works around a bug in any of those in the rare case that one is found, but *every* behavior of your program is predicated on the compiler, VM, and library behaving correctly. If you don't trust that then you cannot use the language.
>>I don't see a design error. I don't even see much >>of a feature hole because GUI construction is [quoted text clipped - 8 lines] > exception that is supposed to be thrown to the > client when add() fails? The internal addition to a Vector is an implementation detail, more exposed than it ought to be but an implementation detail nonetheless. Inasmuch as you are focusing on that detail, I think you are using a faulty basis for your criticism. The implementation of a method or class is driven by its design, not the other way around. Furthermore, as I wrote before, even if you *do* look at the implementation, you have to observe that the specific kind of Collection used (Vector) *doesn't* have any defined failure mode for object addition. This is fully consistent with Collection.add(Object), but more specific in that it requires that every Vector be able to add every object. Given the specifications of Vector.add(Object), ButtonGroup.add(AbstractButton)'s use of that method does not provide any basis for an assertion that the latter should provide some kind of avenue for a failure message to be returned.
>>That would be a very unintuitive GUI element. > > What on earth is "unintuitive" about an "at most > one" set of buttons? It is not the "at most one" part so much as the details you described about your implementation. If you use radio buttons in your button group then the unintuitive part is that clicking on the selected button turns it off. If you use check boxes then the unintuitive part is that no more than one can be selected (though this is probably the most intuitive of these unintuitive options). If you use some new and unique (and visually distinguished) type of button then that in itself is the unintuitive part.
> In my case, I have a feature of a graphical display > which can have one of two states, or not appear, so > I want exactly "A or B or neither, but not both". I > _don't_ want to expend 50% more screen real estate > than is necessary to achieve that result. The advantage of using the extra real estate is in providing an interface that your users don't find surprising. Yes, your users will likely learn whatever interface you provide, but it is less work for you and them both if you provide controls and combinations of controls that operate in a way that they will understand without special documentation or support.
>> Button groups just don't usually work that way. > > Because, according to its own documentation, > ButtonGroup _is_ the implementor of the JRadioButton > "exactly one" behavior; [...] I don't mean ButtonGroup the class, I mean button groups as GUI elements. They (should) provide "exactly one" selection from a group of two or more. You do sometimes see button groups with no option initially selected (more often on web forms than anywhere else), but the meaning of such a group is nowhere near as clear as the meaning of a similar group with an extra "none of the above" option selected. Coming back to the ButtonGroup class, it provides Swing GUIs with button group behavior consistent with button group behavior in other contexts. As such, I don't find it lacking.
> The "issue", if issue there is, is that the "at most > one" behavior is at least as common as the "exactly > one" behavior, but there is no "built-in" > ButtonGroup-paralleling mechanism to implement this > behavior. As should be clear by now, I disagree that the behavior you are looking for is as common as the behavior already provided by ButtonGroup. I also disagree that the behavior you want is desirable, but if you want to continue this discussion in that direction then I think it would be best for both of us to go looking for relevant third-party usability guidelines / studies / whatever (I have already provided a few such below).
>>The ButtonGroup Javadocs suggest instead using a >>sep[A]rate, normal button that has the effect of [quoted text clipped - 7 lines] > as one of several possible ways to implement that > invisible button, No, I didn't miss that, hence my use of the word "suggest." The suggestion is the only specific one given in the ButtonGroup docs (v. 1.4; haven't checked v. 1.5). That in no way makes it a required implementation, but it does distinguish that approach relative to other implementations.
> but by then you've already spent a > visible and distinguished button, making the > invisible button completely pointless, and thus that > recommendation purely bad advice. You do have a point there. Indeed, I think the best option is a visible "none of these" button in the button group. It is both clearest for the user and easiest for the programmer. Are you developing for tiny screens, or something? Otherwise you have an altogether different problem if the required amount of extra screen space is a concern.
> Selecting an already selected button, in the current > implementation, triggers the same signal as > selecting it when it was unselected, which is an > ambiguating design error by Sun. Yes, I saw that when I looked into the question before my first response. Here I'll agree that there is an error, though I would identify it differently: the error is in using AbstractButton as a superclass of both stateless buttons (JButton / JMenuItem) and stateful ones (JCheckBox / JRadioButton). Or at least in defining some behaviors there that shouldn't really be common to both types of button. There is then a secondary error in allowing ButtonGroup to have any AbstractButton as a member, when really it should be able to hold only the latter type (already abstracted as JToggleButton).
> Doing so should > either do nothing at all, or, as I'm seeking, clear [quoted text clipped - 5 lines] > prior state so it can be checked whether the new > "selection" is merely a redundant click. Yes, I would agree that a different type of button class (or different behavior of the existing classes) would afford a better solution than the type of shenanigans you have described implementing in your ButtonGroup subclass. On the other hand, I wouldn't myself have implemented any of it in the first place.
>>As I wrote above, the behavior you describe runs >>against typical GUI conventions. [quoted text clipped - 3 lines] > even possible, and there are no such "conventions" > known to me. There are lots of GUI design manuals and guides, and for the most part they describe very consistent behavior of the common GUI elements. You cannot be unaware that these exist, particularly given your extensive GUI design experience. Not all distinguish between "exactly one" button group behavior and "at most one" behavior, however. Here are some:
http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelin es/index.html http://developer.kde.org/documentation/standards/kde/style/basics/index.html http://axp16.iie.org.mx/Monitor/v01n03/ar_ihc2.htm http://benroe.com/files/gui.html
Notably, for HTML forms, RFC 1866 states "At all times, exactly one of the radio buttons in a set is checked. If none of the <INPUT> elements of a set of radio buttons specifies `CHECKED', then the user agent must check the first radio button of the set initially." (section 8.1.2.4) User agent compliance on this point varies, however.
The Gnome radio button docs state "Exactly one radio button should be set in the group at all times. The only exception is when the group is showing the properties of a multiple selection, when one or more of the buttons may be in their mixed state." (http://developer.gnome.org/projects/gup/hig/draft_hig_new/controls-radio-buttons.html)
As to my GUI design experience (of which I do have some), it is not nearly so important as my GUI *user* experience, because the latter is where I get my expectations of how GUI elements should operate. I daresay the same is true of most of your users. I have never encountered a radio button that toggled off when I clicked it, and therefore I do not expect such behavior. I have occasionally encountered controls that looked like check boxes but acted like radio buttons; this behavior is unexpected and thus less usable, but at least it's easy enough to adapt to.
>>Am I missing something here? > [quoted text clipped - 3 lines] > of the discussion along the way when other terms > were mentioned. Better luck this time. Do continue with the pot shots if your objective is to persuade me to drop this conversation. Otherwise please refrain.
Your original post asked for opinions on whether ButtonGroup was ill-designed for one or both of two reasons:
1) The lack of any success / failure information returned by ButtonGroup.add(AbstractButton), and
2) ButtonGroup's lack of direct support for an "at most one" selection mode.
I take (1) as a general OO design question, and I responded accordingly. I take (2) as an issue revolving around general GUI design and behavior issues, and I responded accordingly, mostly with comments not specific to Java or Swing. One cannot discuss whether or not ButtonGroup's behavior is appropriate without some kind of context for what its behavior ought to be. If you did not like the directions I took the discussion then I can only apologize, but I assure you I did and do have a firm grasp of it. For what it's worth, you have significant control of the lines on which this discussion continues.
 Signature John Bollinger jobollin@indiana.edu
Monique Y. Mudama - 28 Nov 2005 19:36 GMT >> ButtonGroup does not implement Collection, therefore the contract >> for Collection.add(Object) is in no way relevant to the form and [quoted text clipped - 3 lines] > boundary is a fruitful way to decide if a design is robust? That's > language lawyering, not architecting. I absolutely disagree. The user of an API shouldn't have to know what's going on under the hood. "is-a" is therefore important to the user of an API; "has-a" should *not* be.
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Kent Paul Dolan - 29 Nov 2005 23:27 GMT > Kent Paul Dolan penned:
>>> ButtonGroup does not implement Collection, >>> therefore the contract for >>> Collection.add(Object) is in no way relevant to >>> the form and behavior of >>> ButtonGroup.add(AbstractButton).
>> Umm, do you really feel that hairsplitting on the >> is-a/has-a boundary is a fruitful way to decide >> if a design is robust? That's language lawyering, >> not architecting.
> I absolutely disagree. The user of an API > shouldn't have to know what's going on under the > hood. "is-a" is therefore important to the user > of an API; "has-a" should *not* be. Umm, but that's precisely the point. ButtonGroup, conceptually, and thus by implication contractually, is-a Collection, and so should obey the contract for Collection that failure to add an Object to a Collection warns the client-user of the problem by throwing an exception.
That ButtonGroup happens to _implement_ its "Collection"-ness by a has-a mechanism rather than an is-a mechanism is an implementation detail which SHOULD NOT CONCERN the functionality's "consumer".
But in fact, ButtonGroup fails to keep the expected contract for a Collection, violating the Principle of Least Astonishment. Leaving the user-client unwarned when the addition of a JToggleButton to a ButtonGroup fails, is, it seems to me, lousy software engineering as well.
IMAO
xanthian.
Monique Y. Mudama - 30 Nov 2005 04:40 GMT >> Kent Paul Dolan penned: > [quoted text clipped - 15 lines] > Collection warns the client-user of the problem by throwing an > exception. Um, no. ButtonGroup extends Object, as do all Objects. It also implements Serializable. It's not a Collection. The fact that you think it looks like it should be a collection just because it has several of something is irrelevant.
> That ButtonGroup happens to _implement_ its "Collection"-ness by a > has-a mechanism rather than an is-a mechanism is an implementation > detail which SHOULD NOT CONCERN the functionality's "consumer". I'm sorry, but I can't follow you down that path. If the designers thought that we should be able to use a ButtonGroup like a Collection, they would have made ButtonGroup implement Collection. They didn't. End of story.
> But in fact, ButtonGroup fails to keep the expected contract for a > Collection, violating the Principle of Least Astonishment. Leaving > the user-client unwarned when the addition of a JToggleButton to a > ButtonGroup fails, is, it seems to me, lousy software engineering as > well. I didn't expect it to follow the Collection contract, because it doesn't implement Collection. I wonder if you fully understand the idea behind the Java interface. It's a promise of the availability of certain methods. ButtonGroup isn't a Collection, and therefore hasn't made a promise.
I agree that it would be nice to get a warning when an add to a ButtonGroup fails, but I don't think it's anything I've ever checked for. Why would it fail?
> IMAO > > xanthian.
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Kent Paul Dolan - 01 Dec 2005 09:36 GMT > Why would it fail? Because any "sufficiently complex" piece of software _always_ has a failure mode, for one example of a reason. Because it was created by failure prone humans, for another. To believe of _any_ piece of software that "it can't fail" flies in the face of the experience of every living software engineer, and constitutes "living in a fools' paradise" and an incredible degree of naive faith tantamount to unreasoning worship.
IMO based on 44 years of writing software and using software written by others.
xanthian.
John C. Bollinger - 03 Dec 2005 02:41 GMT >>Why would it fail? > [quoted text clipped - 6 lines] > paradise" and an incredible degree of naive faith tantamount to > unreasoning worship. A more precise question might be "Why would it fail predictably?". Yes, an OutOfMemoryError might be thrown. Some RuntimeException might be thrown, even though none are documented. The VM might crash with some internal error. How do you propose ButtonGroup.add() should handle any of these conditions other than simply allowing them to occur? They are all manifestations of bugs or system conditions outside the scope of ButtonGroup, equally applicable to any method; do you suggest that every method should document an exhaustive list of such potential problems? There are no failure conditions /that ButtonGroup is prepared to detect/, so it is not useful to ButtonGroup to declare a mechanism to notify clients of a failure.
 Signature John Bollinger jobollin@indiana.edu
Kent Paul Dolan - 09 Dec 2005 13:34 GMT > There are no failure conditions /that ButtonGroup > is prepared to detect/ You seem to suffer from the same confidence in your own omniscience as does/did Monique. You cannot, _possibly_, _know_ that your statement is true, and in the case, since ButtonGroup implements its Collection-ness internally with Vector, something _required_ to honor the Collection-contract to throw when an add(...) fails, your statement is false. ButtonGroup is perfectly placed to "detect" that its add(...) to its internal Vector produced an exception, and ButtonGroup's "Least Astonishment" behavior, IMO, would be to recognize that it has an obligation to forward Collection-contract exceptions from Vector, and to admit that it does, so that the user-programmer can extend ButtonGroup similarly admitting and forwarding such a thrown exception as part of the implied contract for a Collection, even one that in hidden fashion, implements its Collection-ness via a "has-a" Collection implementation instead of an "is-a" implementation, _precisely_ the sort of implementation detail that "encapsulation" is supposed to _hide_ from us programmers, not to expose as ButtonGroup does by refusing to be subclassed by something that does a "throw".
[Your debate trick to generalize something to the point of ridicule, when such generalization is not a topic of discussion, but instead a simple single case is being discussed, is rejected for the idiocy, dishonesty, and misdirection which it is. Yes, drinking enough water can kill you. No, that isn't a useful argument that drinking water is A Bad Thing.]
xanthian.
Monique Y. Mudama - 09 Dec 2005 17:01 GMT >> There are no failure conditions /that ButtonGroup is prepared to >> detect/ > > You seem to suffer from the same confidence in your own omniscience > as does/did Monique. You seem to suffer from a need to ridicule other people (see your final paragraph). I'll just go ahead and killfile you now to save myself the trouble of reading your posts.
And no, it's not because I disagree with you. It's because you're a jackass.
> [Your debate trick to generalize something to the point of ridicule, > when such generalization is not a topic of discussion, but instead a [quoted text clipped - 4 lines] > > xanthian.
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Thomas G. Marshall - 16 Dec 2005 19:04 GMT Monique Y. Mudama said something like:
>>> There are no failure conditions /that ButtonGroup is prepared to >>> detect/ [quoted text clipped - 8 lines] > And no, it's not because I disagree with you. It's because you're a > jackass. I think you're right. The man clearly does not understand what an OO contract is, and has been attempting to double-talk his way out of admiting that he was wrong.
Thomas G. Marshall - 16 Dec 2005 19:06 GMT Kent Paul Dolan said something like:
>> There are no failure conditions /that ButtonGroup >> is prepared to detect/ [quoted text clipped - 23 lines] > refusing to be subclassed by something that does a > "throw". You just embarrassed yourself even more (hard to believe) with this attempted doubletalk. Pick up a book on OO principals, and learn what "contract", "is-a", and "has-a" *really* means.
<PLONK>
> [Your debate trick to generalize something to the > point of ridicule, when such generalization is not a [quoted text clipped - 5 lines] > > xanthian.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|