Académique Documents
Professionnel Documents
Culture Documents
ShapeVisto™ newHlasPH(Poit™ p) ( return new HasPt” (9); public boolean forCircle(int °) { return pudistanceToO() < ri) public boolean forSguare(int 5) { if (pz < s) oo (py ss) | return tbe: pubes Dosean jorrns(Pain® oShape”») wetsen s-accept(newHasPt(p-minus(q))) } How does this definition differ from the previous one? Good. What does neuwHasPt produce? A now ShapeVisitor™ x its interface implies, ‘And how does it produce that? "By construeting a new instance of HasPe Is neuHlasPt like a constructor? "This virtually indistinguishable from a constructor, whichis why itis above the line that separates constructors from methods. Be a Good Visitor 135Does that mean the new definition of HasPe? tnd the previous one are really the same? Very well, But how doos that help ws with four problem? Cam we override newHasPt when we extend Hasbe”? Lot's override newflasP? in UnionHasPe” That's true. Should it produce a UnionHasPe” wwe, Should we repeat it? HasPt? or a" ‘They are mostly indistinguishable. Both forTranses, the one in the previous and the ‘oue in the new definition of HasPt”. produce the same values when they consume the same values ‘That's not obvious, Yes, we can override any method that we ‘wish to override When we override it, we need to make sure it produces a ShapeVisitor! The latter. Then forTrans in HasPt® keeps producing a UnionHasPt?, if we start with UnionHasPr? Let's just roread it ‘The Ninth Bit of Advice fa datatype may have fo be extended, be forward looking and use a constructor-ike (overrdable) method so that vistors can be extended, too Chapter 9[And that's exactly what we need. Revise the '”” definition of UnionHasPt * the an nance of efor mato pttern If we assemble all this into one picture, what “* do we get? ‘Shape Here itis, ‘lass UrionHasPe? fextendls HasP2” implements UnionVisitor ( UniontasPe” (Point? -p)( super(p. ShapeVistor” newtasPr(Point™ y)( return new UnionHasP0™(p) } Public ‘boolean forUinion(Shape” s,Shape™ £){ if (s.acept(this)) ‘return tee: | else ‘return taccept(this): } [A drawing that helps our understanding of the relationships among the elasses and interfaces ~~ = all ShapeVisitor™ Circle Trans, What does the bex mean? Be a Good Visitor Everything outside of the box is what we designed originally and considered to be ‘unchangeable; everything inside is our 187Does the picture convey the key idea ofthis chapter? Is anything missing? Lets see whether this definition works. What isthe value of new Trans( ‘new CartesianPt(3.7) new Union( ‘new Square(10), new Cirle(10))} aceept( ‘new UnionHasPt™( new CartesianPr(13,17)))? Which method should we use on it?” Whereis forTrans defined? So what should we do now? What is this? And how does that work? 158 "No, It does not show the addition of a ‘onstructorlike method to HasPt” and how it is overridden in UnionHasPt”. Square, but that’s olay We remember that the shape was built with Trans. forTrans, of course Ie is defined in HasPL”. We should determine the value of ‘new Union( new Squate(10), new Cirele(10)) acoept( this newHasPL( new CartesianPt(10,10))) "The current visitor, of course ‘We determine the value of, this. newlfasPe( new CartesianPt(10,10)) and then use accept forthe rest. Chapter 9‘And what do we create? What is the value of new Union( new Square(10), new Cicle(10)) saccept{ ‘new UnionHasPt™( new CartesinPt(10,10)))? How do we do that? Is it tue? ‘Are we happy now? Is it good to have extensible definitions? Very well. Does this mean we can put together flexible and extensible definitions if ‘we use visitor protocols with these cconstructor-like methods? ‘And why is that? Are you hungry yet? Be a Good Visitor ‘The new UnionVisitor™ new UnionHasPt™( new CartesianPt(10,10)) Unions? alao satisfies the interface ShapeVisitor”, so now we can invoke the fortinion method We first determine the value of new Square(10) accept ‘new UnionHasPt™( new CartesianPt(10,10))} Ii is tre, we're done, It i. So we're done and we got the value we expected, Ecstatic ‘Yes. People should use extensible definitions if they want their code to be used more than Yes, we can and should always do so Because no program is ever finished. ‘Are our meals ever finished? 139of LO. Tae. Siar “2 “2Have you ever wondered where the pizza pies " come from? Mere is our pizza pieman clas Pieman" implements Pieman® { Pie? p = now Bot): [pute it eden bic 0 ( P= new Topl tp) return occTop(t): } public int remTop( Object ¢) { [P= Pe inecptinew Ran) | return oceTop(th: } public ing sutstTop( Object n,Object 0) ( P= (Pie”)p.accept(mew Subst”(n,0)) return oceTop(n}: } public int oe Top( Object 0) { return ntegerp-ecent new Occus¥(0)) ‘ntVatuel b | ow so? Haven't we seen Pie®, Top, and Bot ” before? And haven't we seen visitors ike Rem’, Subst”, and Occurs” for various datatypes? Let's not worry about them for a while. The State of Things to Come ‘You should have, because someone needs to make the pi. * This is beyond anything we have seen before. ‘We have seen them * Yes, yes. But what are the stand-alone semicolons about? * Pine, but they are weird 161Here is the interface for Pieman-" interface Piemané { int add Top Object ¢) int rem Top Object ¢) int subst Top( Object n, Object 0} int ce Top( Object 0) , We dont specify fields in interfaces, Anel in any case, we don't want anvbondy ee to seep. Here ate PieVisitor? and Pie? interface PieVistor! { Object forBot) Object forTop( Object tPie® r): } abstract class Pie” { ‘abstract ‘Object acvept(PieVisitor? ash); , Define Bot andl Top. 162 © To it ising 9? * Whatever "They ase very familiar class Bot extends Pie” { Object acrept(PieVistor? ast) { return ask forBot(): } ) ‘lass Top extends Pie { Object ¢: Pie® Top(Object Pie” -r) ( tet rao} Object arcept(PieVistor? ask) { return ask forTop\ ar): ) ) Chapter 10Here is Occurs”. It counts how often some” And this little visitor substitutes one good topping occurs om 1 pie topping for another. class Occurs” implements PieVisito’ (|_| class Subst’ implements PieVisitor” { Oo Oo n | Oct (Objet a) { | | Shee | | = } | | Subst” (Object .n,Object 0) { | pave ova jorbo ( im | Papa jjteee | public Object forTop{Object Pie? r) { public Object forBot() { ble Objet earn new Bot) ‘rn publ Objet for Top Obes te») (1 tw Itge( (tae) ioepuntt} | (ree ptthis)) return nate) “hw Tn) anni) + ue se rou eturn rcpt): ww Top(t(PiP yep this) | ) Great! Now we have almost all the visitors" We remember that one. too. sine Rem”, which ren implements PieVistor” { [class Rem” Object: Rem” (Object 0) { o= 0) publie Object forBot() { return new Bot) } } public Objet forTop(Object Pe? »)( it (omit) return rari) else return ‘new Top(4(Pie™ arp this): } The State of Things to Come 163new Pieman™().oceTop(mew Anchowy())? Which pie? [And howe many anchovies are on that ple? And what isthe value of yew Pieman'().adi'Top(new Anchovy(})? ‘Thue. If we wish to determine the value of new Pieman().addTop(new Anchovy()). understand what yew Top(new Anchovy().p) return ccrTop(new Anchovy()) "We fist create @ Pieman and then sk how ‘many anchovies accut on the pi. ‘The pie named p in the new Pieman* * None ‘That's right. But that's what happens when "* ‘your have one too many double espressos. Here it means that p changes and that fu references to p reflect the change Whew dows the future begin? That's precisely what a stand-alone semicolon means. Now do we know what return oceTop(new Anchovy()} produces? 164 That's where those stand-alone semicolons ‘come in again. They were never explained Yes, we must understand that. There is no umber + in the world for whieh perth, 0 why should we expect there to be a Java p ssuch that p ew Top(new Anchovy().p)” So what does it mean? ‘And the change is that p has a new topping right? Does it hegin below the stand-alone semicolon? It produces the number of anchovies on p. Chapter 10‘And how many are there? And now what isthe value of yew Pieman().addTop(new Anchowy())? No, its not. Take a close Jook. We created a ” new pieman, and that pieman added only ‘one anchor to his p. ‘Yes, there i, Take Took at this Piemant y = new Pieman™() ‘What isthe value of y.addTop{new Anchovy())? And now what is the value of y.sulstTop(new Tuna(),new Anchovy())? Correct. So what is the value of yoceToplnew Anchovy())? Very good. And now take s lok at this Pieman® yy = new Pieman™() What i the value of add Top( new Anchovy()) madd Top{new Anchovy()) ywaddTop(new Salmon()) ‘The State of Things to Come We added one, so the value is L Ws 2, isn't it? Oh, isn't there a way to place several requests with the same pieman? Olay, y stands for some pieman, 1, We know that Stil 1. According to the rules of semicolon ‘and =, this replaces all anchovies on p with ‘unas, changes p. and then counts how many tunas aze on p. 0, because 9 p anchovies. ger contains any What ate the doing at the end? 165,Because this is only half of what we want to Took at. Here isthe other bale ‘yuaddTop(new Tuna) ‘yyaddTop(new Tuna()) ‘nssubstTopltew Tuna().new Anchowy))? Aud what is the value of y.rem Top(new Tuna()) ‘after we are through with all that?” Does that mean remTop always produces 0? Now what is the value of y-oceTop(new Salmon())? ‘And how about y.oceTop(new Salmen())? Is yy the same pieman as before? So is it the same one? When we asked yy to substitute all anchovies by tunas, did the pie change?” Does that mean that anybody can write yup = new Bot() ‘and thus change a pieman like yy? 166 4, First we add two anchovies, then salmon, and two (unas. Then we substitute the two anchovies by two tunas, So y's pie contains four tunas Ws 0, because rem Top first removes all unas ‘and then counts how many there ae lft ‘Yes, it always does 0, because y and yy are two different piemen No, it changed When we eat a pizza pie, we change, but we are still the same. ‘The p in yy changed, nothing else No, because yp's type is Pieman?, p isn’t available. Only addTop, remTop. subst Top and occTop are visible. Chapter 10Isn't it good that we didn't include pin” Piemant? Clear like soup? “ Can we define a different version of Subst” so ™ ‘that it changes toppings the way’ a pieman changes his pes? ‘And that's what we discuss next. Do you reed a break’? ‘Compare this new PieVisitor with the fest“ one in this chapter | interface PieVistor™ { | Object frBot(Bet that) | Object JorTon(Top tha) ‘True. Here is the unchanged datatype. abstract class Pie® { abstract Object eccept(PieVisitor! ask) ve Define the Bot variant Is it? Why does it use this? . The State of Things to Come ‘Yes, with this trick we can prevent others from changing p (or parts of p) in strange ways. Everything is clear now. ‘Tas like chicken soup, " We can't do that yet No, a cup of coffee will do Tt isn't all that different. PieVistor? must, still provide two methods: forBot and forTop, except that the former now ‘consumes a Bot and the latter Top. ‘The definition is straightforward class Bot extends Pie® { Object accept(PieVisitr® ask) { return ask forBot( this): } } We only have one instance of Bot when we use forBot, namely this, so forBot is clearly supposed to consume 167‘That's progress. And that's what happens in Top, 100, class Top extends Pie? { Object f Pre? Top(Object Pie” -r) { ti on} Object accept(PieVisitor™ ask) ( return ask forTop( | Edessa anaes Modify this version of Occurs” so that it Implements the new PieVistor! class Occurs” implements PieVisitor™ { | Object Occurs¥ (Object <0) { a= a} ~ public Object forBot() { ‘return new Integer(0); } public Object forTop(Object #,Pie” r) { if tego) return new Ince (integer) | (r-accept(this))) | neve) i 0 | else | | Feturn vacept(ehis); } | , How does forBot change? 168 “Interesting © ‘The forBot method basically stays the same, but forTop changes somewhat las Oca implements Pier (_] Object es bit -a){ public Object forBot(Bot that) { return new integer(0); } [| public Object forTop(Top that) { If (that tequols(a)) return new Integer (Integer) (thatr.accept(this))) sntValue() +05 | else return thaccept(this); } | Boo “It now consumes « Bot, which is why’ we had to add (Bot that) behind its name. Chapter 10How does forTop change’? And? Isn't that easy? ‘Then try Rem’. Do we need to do Subst”? And indeed, it is. Happy now? Oh, Points? They will show up later. ‘The State of Things to Come © Ie no longer receives the field values of the corresponding Top. Instead it consumes the entire objeet, which makes the two fields fvailable that and that r “With that, we can teplace the Rilds fan + with that. and that, ‘This modification of Occurs” certainly i Tes easy; we use the same trick, ‘lass Rem” implements PieVisitor! ( Object: Rem’ (Object -0) { ona} public Object forBor(Bot that) { return new Bot() } public Object forTup(Top that) { If (o.oqual(thet.t)) return thot.r.accept( this) else return new Top that. (Pie? that. aceept(this)}; } "Not really: It should be just like Rem” So far, so good. But whats the point of this © Serious 169Here is the point, What is new about this version of Subst”? Object 0 Subst” (Object -n, Object 0) { public Object forBot(Bot that) { return that: } ublie Object forTop(Top that) { it (o-puals( thoes) { | ‘rant ‘that-raccept( this) return that: } else { that. r-accept(this) return that: ) ‘There are no news Don't they say “no mews i good news?” ‘Yes, because we want to define a version of |" Subst” that modifies toppings without constructing a new pie. What do the methods of Subst” always return’ So how do they substitute toppings? ” 170 Does this saying apply here, 100? ‘That ‘a way of putting it They always return thet, whichis the object that they consume By changing the that before they return Specifically, they change the ¢ field of that to ‘when it equals 0. Chapter 10What? Correct. And from here on, thet holds the new topping. What is that. accept( this) about? Is there anything else to say about the new Subst”? Do we have to change Pleman? Is it truly safe to modify the toppings of a pie? Can we do LedSubst” now without cresting new instances of LtdSubst” or Top? ‘The that dos it. In the previous Subs, r.accept(this) created a mew pie fom 7 with all toppings appropriately substituted. In our new version, thatraceept(this) modifies the pier ‘contains the appropriate toppings. Not really: It does what it does, which is ‘what we wanted." No, we didn’t change what the visitors do, wwe only changed how they do things. ‘Yes, because the Pieman™ manages the toppings of p. and nobody else sees p. Now that's a piece of pie, ‘The Tenth Bit of Advice When modifications to objects are needed, use a class to insulate the ‘operations that modify objects Otherwise, beware the consequences of your actions ‘The State of Things to Come mHere is a true dessert, It will help us understand what the point of state is. abstract class Point? { nt =, int yi, Point? (int int -) { ) “The datatype has three extensions. class CartesianPt extends Point? { CartesianPt(int int -y) { super(.7, int dstanceT0O0 ( eum ives + Fi} boolean closerToO(Point® p) { return, distanceToO() < padistance 00); } Point® minus(Point® p) { return new CaresianPt(x ~ pry —p.v)s } abstract int distanceT00() y Aren't we missing a variant? im ‘clas ManhattanPt extendls Poin ( | ManhattanPt(int _2,imt _y) { super(-9):} | inv dwncetooO return x+y; } | ———EEE [class ShadowedManhattanPt ‘extends ManhattanPt { int A. int 455 ShadowedManhattanPt(int 7 int -y, int -A,, int Ay) ( super(-2.-0) 4, ‘distanceToO() { return, ‘super.distanceToO()+A, + Ay: } ) essnsdas seeeteaNNanadstaTaTateeetazEa| Yes, we are missing ShadowedCartesianPt Chapter 10Good enough. We won't need it, Here is one point: new ManhattanPt(l,4) If this point represents a child walking down the streets of Manhattan, how do we represent his movement? ‘Yes. Add to Point? the method moveBy, which consumes two ints and ehanges the fields of « point appropriately ‘The method should return the new distance to the origin. Let ptChild stand for new ManhattanPt(1.4) What is the value of pIChild distance ToO()? The State of Things to Come "Shouldn't we add a method that changes all the feds of the points? First we must know what the method is supposed to produce. Now we know how to do this, abstract class Point? ( int 2 int vy: Point?(int z,int .») { ootean closerToO(Point p) { return distonceT0O() < pdistanceToO() } Point? minss(Poit™ 2) { return snow CartsianPx Int moveBylint 3, pert ae Pry py) } int 45) { ¥ +4, return distanceT0O();} abstract int distance ToO(); } 13What is the value of otChild. moveiy(2.8)? Good. Now let's watch a child with a hhlinnnfiled balloon that casts « shadow Let ptChildBalloon be new ShadowedManhattanPt(1.4..1) What is the value of pICHildBalloon distance ToOK) What is the value of ptChildBattoon.moveBy(2.8)? Did the balloon move, too? 0 Isn't that powerful? ‘The more things change, the cheaper our Hlesserts get Correct bt ow we ate through and i is time to go out and to celebrate with a grand dinner amt 15. 7, of course. ‘Yes it just moved along as we moved the point Ik sure is. Wo added one method, used it and everything moved ‘Yes, but to get t0 the dessert, we had to work quite hard, Don't forget to leave a tip. Chapter 10‘You have reached the end of your introduction to computation with classes, interfaces, and ‘objects. Ate you now ready to tackle a major programming problem? Programming requires two kinds of knowledge: understanding the nature of computation, and discovering the lexicon, features, and idiosyncrasies of a particular programming language. ‘The frst of these is the more dificult intellectual task. If you understand the material in this book, you have mastered that challenge. Still, t would be well worth your time to develop a fuller understanding of all the ‘capabilities in Java—this requires getting access to a running Java system and mastering those Idiosyncrasies. If you want to understand Java and object-oriented systems in greater depth, take a look atthe following books: References 1. Arnold and Gosling, The Jana Programming Language, Addison-Wesley, Reading, Mas- sehsetts, 1906, 2. Buschmann, Meunier, Rohnert, Sommerlad, and Stal A System of Patterns: Pattern Ontented Software Architecture. John Wiley & Sons, Ltd. Chichester, Europe, 1906, 3. Firesmith and Eykholt, Dictionary of Object Technology, SIGS Books, Inc., New York, New York, 1995 and Prentice Hall, Englewood ifs, New Jersey, 1995. 4. Gamma, Helm, Johnson, and Vlissides. Design Patterns. Addison-Wesley, Reading, Massachusetts, 1994 Gosling, Joy, and Steele, The Java Language Specifiation. Addison-Wesley, Reading, Massachusetts, 1996 6. Proe. Design Patterns for Object-Oriented Software Development. Addison-Wesley, Read- ing, Massachusetts, 1994 (Commencement 7This is for the loyal Schemers and MLers. No, we would forget factor [interface (0 oo! apply(T? x); } splements 00-00" { Public 0-0" apply(o—o! fact) { return new Fact{fact): ) pb lass Fact implements oo! { Object apply( Object); } | one? fact Fact(o-of fact) { foct = facts} [interface 0-00" ( public Object apply(Object i) { om oF appiy(o—o" 2} | "ine ini = (tnteger))-nt Vatu) } if (inti == 0) return new Integer); | interface 20-00-00" ( ) | interface oo! { | : = = J ‘0-+07 apply(oo—oo! 2); a tage z a | inti class Y implements 00-00-00" ( (Integer) Fas ents See ew tec ~1)) return new H(f).apply(new H(f)); } ant Value()}; non [ieee all [tase # implements T | 2000! J | Hose 1 | =f) | pu ot apt) ( Need return fapplynew (2): } | | class G implements oo" ( Ts | erat | public Object appy( Object y) { return (zappy(2)).apply(y): } } lCopyrighted materi Index Ads, 128 salty, 188 ‘rchowr 9,5, 6h 5, 68 72 ‘pte, ot ase, 10 brsFeie” 104 isnt 2 bist, 102,109 Bek 9.7, 8, 8S, 86, 1, 9,162, 167 Bd, 00, 01, 10,10, 122 bree, 101 CrtesinPs, 513,37, 98-40, 199,172 (Chere 4,5 61, 65 Const, 118 Copper, 2 Grom 29,66, 55 Digge, 2 agen i n9 ‘dulce TiO, Uf, 8,10, 14, 2,172 Empty, 124 eu, 72,7, 100 Ber, 119 EpVister, 118 Fic, 100 Fah, 69,72 ais, 29 Habe’, 147,155, iWeige, 108 seu ant Isp 113 ssligetirian, 25,27 levageiin 6 ‘Vane, 3, 31,36, MeeViitr’, 7 Kebab, 25,36 Laye?, 10 * aan, 100 Urata 96, 07,199 906 MarhananP, 5, 13,98, 99,199,172 ‘mas, 130 mote, 1 elles, 15, 15T Rime 7. cop, 161 (ecu, 24, 165,168 OneMereThan. 7,19 ‘Onon, 1,27 25, 36, 50,2 fonOnin 1 27 OnyOsone 37.0 Penta Pepper 4.37 Pie TR 8,25, 8, 102, 107 Bevin? 2 162 1 Planar, 162 Peamae’4 6h ae?) 20 pier, 20 Pont? 5,13, 40, 199,172,178, prod, i2t Pred ‘119Radish, 28.36 ema 5, 9, 0) Rena, oe 7h 73 Rents, 74 Rem, 77,7, 98, 163, 160 emin, 7 ae Sate, 90 Som 5 Salmon, 6.72 Sant Sausage. 8,58, 63-65, Sexong®, 4 ser. a SetBa, 16,1 ShafowedCaresanPt, 14, M2 ‘Shadomeadtanatanee, 138,172 Shane! 165 ShapeVitor 148 Shah, 10,27, 59,08 Shien, 28,30 Sie 29 Shaw 16, 27,59, 02 Stee, 0 Spiaeh, 5 Spy 10D, 01, 108,10, 122 Shui, tis Ides shite, 52.58 SubARC?, 66 Suba®, iat 1 Subs a Subs, 85,87, 80,4, 152496, 16,179 Subse | abatToy 11 Swed, 29 Tomato, 16.27.28, 30,59, 2 op, 8, 78.85, 85,86, 91,93, 162168 TooAwe?. 66 Tram th ee, 100, 201, 107,109, 22 Tenater? 112 ‘Subs, Ut Meise! 109 nin, 149, 150 UnioViter, 150 Wood, 20” occ, 1 Copyrighted materialCopyrighted material A Little Java, A Few Patterns, ‘Matthias Felleisen and Daniel PTviedman Foreword by Raiph .Johnon Drawings by Duane Bibby 0 snterne na very short tine ithas become one of the moet