1 / 36

Advanced Object Oriented Systems

Advanced Object Oriented Systems. (CM0318) Lecture 8 (Last updated 15th February 2002). Purpose of Lectures 8 & 9. To illustrate why Smalltalk is different, in particular because: implementation of system classes is readily available

oswald
Download Presentation

Advanced Object Oriented Systems

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advanced Object Oriented Systems (CM0318) Lecture 8 (Last updated 15th February 2002)

  2. Purpose of Lectures 8 & 9 • To illustrate why Smalltalk is different, in particular because: • implementation of system classes is readily available • debugging tends to involve understanding system classes as well as one’s own • Smalltalk is a highly dynamic system

  3. Topics • Implementation of collections • Introspection and dynamic modification of classes/objects • The Model-View-Controller paradigm • Debugging strategies • (Implementation & introspection are the topics of the present lecture)

  4. Partial Collection hierarchy ProtoObject Object at: at:put: Collection includes: isEmpty add: remove: do: size Bag SequenceableCollection , first at:ifAbsent: indexOf: ArrayedCollection Array (“Variable subclass”) String < = beginsWith: Symbol OrderedCollection Set Dictionary at: at:put: includesKey:

  5. Recommended Smalltalk reading • Byte, August 1981 (dedicated to Smalltalk) • Goldberg, A., and Robson, D., ‘Smalltalk-80 : the language’, Addison-Wesley, 1989. • Goldberg, A., ‘Smalltalk-80 : the interactive programming environment’, Addison-Wesley, 1984.

  6. Implementation of Collections • NB it’s essential to annotate these handouts - otherwise the code won’t make much sense!! • You can verify all of what I am telling you in this lecture simply by browsing in Squeak - indeed, the main message is the ‘openness’ of the Smalltalk code. We’ll see how this affects debugging, etc., later.

  7. Implementation of Array • Creation method: class method new:, which is actually inherited from Behavior(Remember Array is itself an object; instance of its metaclass, which is a subclass - with a few intermediaries in between - of Behavior).

  8. Array (ctd.) • Main accessing methods: at: (implemented in Object), at:put: (implemented in Object), size (implemented in ArrayedCollection) • Example of code to replace every element in an array by that element + 1: a ← #(3 4 5). 1 to: a size do: [:i|a at: i put: (a at: i) + 1]. ^a

  9. Array (ctd.) • Source code for Object>>at:put: at: index put: value "Primitive. Assumes receiver is indexable. Store the argument value in the indexable element of the receiver indicated by index. Fail if the index is not an Integer or is out of bounds. Or fail if the value is not of the right type for this kind of collection. Answer the value that was stored. Essential. See Object documentation whatIsAPrimitive." <primitive: 61> index isInteger ifTrue: [self class isVariable ifTrue: [(index >= 1 and: [index <= self size]) ifTrue: [self errorImproperStore] ifFalse: [self errorSubscriptBounds: index]] ifFalse: [self error: (self class name) , 's are not indexable']]. index isNumber ifTrue: [^self at: index asInteger put: value] ifFalse: [self errorNonIntegerIndex]

  10. Array (ctd.) • Methods like at:, at:put: are defined in Object because there are 2 fundamental types of class: • Fixed (named instance variables only) • Defined <class> subclass: #<classname> ... • Variable (named instance variables and subscripted instance variables) • Defined <class> variableSubclass: #<classname> ...

  11. Inst var n-1 Inst var n-1 Inst var 1 Inst var 2 Inst var n Inst var 3 Inst var 4 Inst var 5 Inst var n Inst var 1 Inst var 2 Inst var 3 Inst var 4 Inst var 5 1 2 3 m FIXED VARIABLE

  12. Array (ctd.) • Testing for equality (inherited from SequenceableCollection) = otherCollection "Answer true if the receiver is equivalent to the <otherCollection>. First test for identity, then rule out different species and sizes of collections. As a last resort, examine each element of the receiver and the <otherCollection>." | size | self == otherCollection ifTrue: [^ true]. (self species == otherCollection species) ifFalse: [^ false]. (size ← self size) = otherCollection size ifFalse: [^ false]. 1 to: size do: [:index | (self at: index) = (otherCollection at: index) ifFalse: [^ false]]. ^ true

  13. Array (ctd.) • Testing for inclusion (inherited from Collection): includes: anObject "Answer whether anObject is one of the receiver's elements." self do: [:each | anObject = each ifTrue: [^true]]. ^false

  14. Array (ctd.) • Iteration - do: (inherited from SequenceableCollection) do: aBlock "Refer to the comment in Collection|do:." 1 to: self size do: [:index | aBlock value: (self at: index)]

  15. OrderedCollection • Similar to Vector in Java • Comprises an Array, a firstIndex and a lastIndex (only part of the array is used). So an ordered collection with elements 34, 46, 25 might be represented thus: Element no Contents 1 ? 2 ? 3 34 <- firstIndex=3 4 46 5 25 <- lastIndex=5 6 ? 7 ?

  16. Compared with Vector ... • Allows the collection to grow at the beginning and the end.

  17. OrderedCollection example oc ← #(3 4 5) asOrderedCollection. oc addFirst: 'ho'. oc addLast: 'hoho'. ^oc at: 2 • Result is 3.

  18. OrderedCollection (ctd.) • Instance creation (class methods): new ^self new: 10 new: anInteger "If a subclass adds fields, then it is necessary for that subclass to reimplement new:." ^ super new setCollection: (Array new: anInteger)

  19. OrderedCollection (ctd.) • Instance creation (instance methods): setCollection: anArray array ← anArray. self reset reset firstIndex ← array size // 3 max: 1. lastIndex ← firstIndex - 1

  20. OrderedCollection (ctd.) • Accessing using at: at: anInteger "Answer my element at index anInteger. at: is used by a knowledgeable client to access an existing element" (anInteger < 1 or: [anInteger + firstIndex - 1 > lastIndex]) ifTrue: [self errorNoSuchElement] ifFalse: [^ array at: anInteger + firstIndex - 1]

  21. OrderedCollection (ctd.) • Adding a new element: addLast: newObject "Add newObject to the end of the receiver. Answer newObject." lastIndex = array size ifTrue: [self makeRoomAtLast]. lastIndex ← lastIndex + 1. array at: lastIndex put: newObject. ^ newObject

  22. OrderedCollection (ctd.) • Growing ... makeRoomAtLast | newLast delta | newLast ← self size. array size - self size = 0 ifTrue: [self grow]. (delta ← firstIndex - 1) = 0 ifTrue: [^ self]. "we might be here under false premises or grow did the job for us" 1 to: newLast do: [:index | array at: index put: (array at: index + delta). array at: index + delta put: nil]. firstIndex ← 1. lastIndex ← newLast

  23. OrderedCollection (ctd.) • More growing: grow "Become larger. Typically, a subclass has to override this if the subclass adds instance variables." | newArray | newArray ← Array new: self size + self growSize. newArray replaceFrom: 1 to: array size with: array startingAt: 1. array ← newArray

  24. Exercise (unassessed) • Investigate: • Other methods implemented by/inherited by Array and OrderedCollection • The implementation of the Set class

  25. Introspection; dynamic modification to classes/objects • Java provides limited introspection via the reflection API. Main things you can do: • determine an object’s class • get information about a class’ fields, methods, etc. • create an instance of a class whose name is only determined at run-time • get and set the value of an object’s field • invoke a method on an object • these things can be achieved even if the method name, for example, is only determined at run-time

  26. Suggested reading • Tutorial on Java reflection: http://web2.java.sun.com/docs/books/tutorial/reflect/index.html

  27. Example: invoking a method import java.lang.reflect.*; class SampleInvoke { public static void main(String[] args) { String firstWord = "Hello "; String secondWord = "everybody."; String bothWords = append(firstWord, secondWord); System.out.println(bothWords); }

  28. public static String append(String firstWord, String secondWord) { String result = null; Class c = String.class; Class[] parameterTypes = new Class[] {String.class}; Method concatMethod; Object[] arguments = new Object[] {secondWord}; try { concatMethod = c.getMethod("concat", parameterTypes); result = (String) concatMethod.invoke(firstWord, arguments); } catch (NoSuchMethodException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } catch (InvocationTargetException e) { System.out.println(e); } return result; } }

  29. Doing the same in Smalltalk meth ← #,. ^'Hello ' perform: meth with: 'everybody.'

  30. Finding an object’s class • Simply send it the message class • Example: t ← Test new. ^t class • Result: Test

  31. Finding out if an object responds to a message • Send respondsTo: to an object or canUnderstand: to a class. E.g. o ← 'hello'. ^o respondsTo: #first Collection canUnderstand: #size

  32. Implementation of canUnderstand: canUnderstand: selector "Answer whether the receiver can respond to the message whose selector is the argument. The selector can be in the method dictionary of the receiver's class or any of its superclasses." (self includesSelector: selector) ifTrue: [^true]. superclass == nil ifTrue: [^false]. ^superclass canUnderstand: selector • (Implemented in class Behaviour)

  33. Finding all messages to which it responds • Collection allSelectors • Returns a Set of Symbols: • Set (rootStubInImageSegment: hash copyAddedStateFrom: propertyList anyOne cCode: hashMappedBy: caseOf:otherwise: wantsSteps truncated ifNil:ifNotNil: asBag respondsTo: species detectMax: caseOf: initialDeepCopierSize range confirm: adaptToInteger:andSend: ~~ readDataFrom:size: windowActiveOnFirstClick * perform:with: finalize comeFullyUpOnReload: primitiveError: deepCopy ...

  34. Compiling a new method into a class • Suppose that we have a class Test. Then evaluating: Test compile: 'double: aNumber ^aNumber * 2’ creates a new method for Test on the fly! So now we can do: Test new double: 42 and get the result 84.

  35. Individual object behaviour • Consider the following class definition: Object subclass: #Test instanceVariableNames: 'meth ' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Objects' • Instance methods: setSpecialMethod: aBlock meth ← aBlock specialMethod: aValue ^meth value: aValue

  36. Indiv. object behaviour (ctd.) • Then can create objects that behave differently. E.g. t1 ← Test new. t1 setSpecialMethod: [:i | i * 2]. t2 ← Test new. t2 setSpecialMethod: [:i| i - 1]. ^Array with: (t1 specialMethod: 42) with: (t2 specialMethod: 42) • Result is: (84 41 )

More Related