Object IdentityObject ProtocolEquality vs. IdentityEqualitySlide 5New ObjectsSharingSlide 8What is the value of?Information HidingSlide 11Violating Information HidingSlide 13CopyingSlide 15Slide 16Slide 17StreamsUses of StreamsReadStream ProtocolReadStreamIteratorSlide 23Stream ProtocolLineStreamCreating a LineStreamSlide 27Slide 28AdaptersInfinite StreamsSlide 31SelectionStreamsSlide 33Slide 34PrimesSlide 36BlocksSlide 38ReuseCompositionFileStreamsOther operations on filesInheritance as ParameterizationInheritance and PolymorphismSpecification InheritanceInheritance for code reuseSlide 47How to Use InheritanceObject Identity= vs. ==copying objectscreating objectsObject ProtocolOperations understood by all objects:== anObject identity - same object= anObject equality - same value~~ anObject different objects~= anObject different valuesEquality vs. IdentityEquality is user defined.= anObject^self == anObjectIdentity is system defined.== anObject<primitive: 110>Equality(Date newDay: 40 year: 1995) ==(Date newDay: 40 year: 1995)is false, because they are physically two distinct objects. However, they represent the same value, so they are equal.Each object has its own region of memory.“Object ID” is essentially a pointer.Variable contains object ID, not the space of an object.“Passing an object as an argument” means passing the object ID.New ObjectsA new object is different from any existing object.X new == X newis almost always false.“Rectangle new = Rectangle new” is true.SharingInvoiceInvoiceInvoiceInvoiceInvoiceInvoiceInvoiceInvoicenamename““Ann Jones”Ann Jones”Oct. 3, ‘75Oct. 3, ‘75Oct. 3, ‘75Oct. 3, ‘75Oct. 4, ‘75Oct. 4, ‘75““Ann Jones”Ann Jones”““Joe Smith”Joe Smith”namenamenamenamedatedatenamenamedatedatedatedatedatedateSharingSharing saves space.Sharing makes changes to one object visible to another.Sharing is always safe when objects are immutable.What is the value of?(Point x: 3 y: 17) == (Point x: 3 y: 17)(Point x: 3 y: 17) = (Point x: 3 y: 17)'this is a string' == 'this is a string'#aSymbol == #aSymbolInformation HidingAn employees transactions are entirely hidden from clients.To add an transaction, use postTransaction:There is no way to access transactions outside Employee.Information HidingSuppose you want to iterate over transactions of an employee.Alternative 11) Add #transactions method2) anEmployee transactions do:Violating Information HidingAn accessing method discloses information.anEmployee transactions add: (Paycheck new)anEmployee transactions removeVery dangerous!Information HidingAlternative 2transactionsDo: aBlocktransaction do: aBlockAlternative 3transactions^transactions copyCopying"shallow copy" -- copy object, but not contents of object"deep copy" -- copy object and contents of object, recursively(usually VERY selectively)Copying is usually shallow copying.CopyingIn class Object:copy^self shallowCopy postCopyTemplate Method pattern!Redefine postCopy to change the way to copy variables, not copy.OCollectionOCollectiontransactionstransactionsOCollectionOCollectionTimecardTimecardEmployeeEmployeePaycheckPaycheckTimecardTimecardtransactionstransactions| t s |t := Point x: 1 y: 17.s := t copy.s x: 5.s = t| t s || t s |t := Point x: 1 y: 17.t := Point x: 1 y: 17.s := t.s := t.s x: 5.s x: 5.s = ts = t| t s || t s |t := Point x: 1 y: 17.t := Point x: 1 y: 17.s := t copy.s := t copy.s == ts == t223311StreamsStream protocolObject compositionUses of StreamsExternal iteratorParsingFormatted outputDataflow computingFile I/OReadStream ProtocolReadStreamnext, atEnd(do:, nextMatchFor:)#next is valid if #atEnd is false.ReadStreamt := ReadStream on: ‘this is the input’.[t atEnd] whileFalse: [t next = $p ifTrue: [^t]]]IteratorInternal Iterator - do:External Iterator - streamsInternal iterator is easier to use, but less powerful.External iterators needed for simultaneous iteration.Iterator“return true if streams equal”[stream1 atEnd | stream2 atEnd]whileFalse:[stream1 next = stream2 nextifFalse: [^false]].^stream1 atEnd & stream2 atEndStream ProtocolWriteStreamnextPut:(nextPutAll:, cr, tab, space)LineStreamTakes character stream and returns one input line at a time.aStream := LineStream on: (‘stuff’ asFilename readStream).inputLine := aStream next.Creating a LineStreamClass methodon: aStream^self basicNew on: aStreamInstance methodon: aStreaminputStream := aStreamnext| outputStream |outputStream := WriteStream on: (String new: 20).inputStream do: [:eachChar | eachChar = CR ifTrue: [^outputStream contents]ifFalse: [outputStream nextPut: eachChar]].^outputStream contentsLineStreamatEnd^inputStream atEndClass methodinitialize"LineStream initialize"CR := Character crAdaptersStream ofStream ofStringsStringsStream ofStream ofCharactersCharactersTranscript show: Transcript show: (LineStream on: (LineStream on: (‘stuff’ asFilename readStream))(‘stuff’ asFilename readStream)) nextnextClientClientInfinite StreamsIt is easy for streams to be infinite; they just always return false for atEnd. IntegerStream is a class of streams that return the positive integers in order. It has one instance variable, value.atEnd^falsenext| temp |temp := valuevalue := value + 1^tempinitinit value := 1value := 1Class methodClass methodnewnew ^super new init^super new initSelectionStreamsThe select: message to a stream should produce a SelectionStream. SelectionStream has four instance variables, selectBlock, nextValue, atEnd, and stream.atEnd^atEndnext| temp |temp := nextValue.stream do: [:each | (selectBlock value: each) ifTrue: [nextValue := each. ^temp]].atEnd := true.^tempselect: aBlock on: aStreamselectBlock := aBlock.stream := aStream.atEnd := false.self next.PrimesPrimeStream has one instance variable, stream.initstream := IntegerStream new.stream next "start stream with 2"atEnd^falsenext| nextPrime |nextPrime := stream next.stream := stream select: [:i |( i \\ nextPrime)~~ 0].^nextPrimeBlocksBlocks can cause temporaries to have a long lifetime.IntegerStreamCollectStreamCollectStreamCollectStreamblockblockblock235BlocksBlocks point to method contexts, and method contexts are stored until nothing (i.e. no called contexts and no blocks) needs them.ReuseInheritance vs. compositionInheritance: Stream defines standard interface and shared code.CompositionSelectionStream can be composed with other streams to make a new kind of stream. Most of PrimeStream is reused from
View Full Document