In the interest of fairness to Good Old Java, this is not as much of a show-stopper as the examples make it appear.
On Feb 13, 10:14 pm, Jeff Grigg <jeffgr...@charter.net> wrote: > The problem is that when you use method chaining on classes that > extend other classes and which add methods, you MUST always call > subclass methods before calling superclass methods -- otherwise it > won't compile. First, we can go a tad further than the parent post's example; as Jeff showed, even though this new Sub().setSubStuff().setBaseStuff(); will compile, this new Sub().setBaseStuff().setSubStuff(); will not. Even worse, this Sub badSub = new Sub().setSubStuff().setBaseStuff(); won't either! Oh, horrors! Java is completely broken! (I'm kidding! ;-) Back in Java 101, we learned that Java allows implicit upcasting, but requires explicit downcasting. The compiler barfs on the second line of this: Base stealthSub = new Sub(); Sub notSub = stealthSub; but uncomplaingly takes this: Base stealthSub = new Sub(); Sub notSub = (Sub) stealthSub; because the programmer took responsibility for guaranteeing the appropriate relationship. So, back to the original examples, this: Sub badSub = new Sub().setSubStuff().setBaseStuff(); fails because in the general case setBaseStuff() might really return an instance of Base that is incompatible with Sub. But the programmer can write code that explicitly states her/his intentions and gives the compiler a promise of type-safe behavior, as in: Sub goodSub = (Sub) new Sub().setSubStuff().setBaseStuff(); The same solution applies to the chained methods; I simply guarantee the compiler that I haven't broken the "chain of possession" with a cast, either for the assignment to a variable of type Sub: Sub goodSub = (Sub) new Sub().setSubStuff().setBaseStuff(); or within the sequence of chained method calls: ((Sub) new Sub().setBaseStuff()).setSubStuff(); both of which DO compile. So, its a bit of an exaggeration to imply that we CAN'T call Sub methods first. We simply have to be explicit when the instance sheds its Base overcoat. (I'm not going to mention monads here! ;-) Do I think this solution is beautiful and graceful and effortless? Not really. But it does allow us: - to compile our code, - to talk fearlessly about the various orderings of builder method calls and whether there are some good practice statements waiting to emerge, - to calmly examine new language proposals while continuing to write and compile code that is explicit and works, and, - (most importantly, IMHO) to avoid completely changing the meaning of void from "nothing will be returned". I regard the redefinition of void to be a much greater threat to the readability of Java than the need to insert an explicit cast now and then. -jn- --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to javaposse@googlegroups.com To unsubscribe from this group, send email to javaposse+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/javaposse?hl=en -~----------~----~----~----~------~----~------~--~---