Why not make the return type <T extends This>? ~~ Robert.
joel.neely wrote: > 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 <[email protected]> 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- > > > > -- ~~ Robert Fischer. Grails Training http://GroovyMag.com/training Smokejumper Consulting http://SmokejumperIT.com Enfranchised Mind Blog http://EnfranchisedMind.com/blog Check out my book, "Grails Persistence with GORM and GSQL"! http://www.smokejumperit.com/redirect.html --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/javaposse?hl=en -~----------~----~----~----~------~----~------~--~---
