03G-1
Everything is an ObjectEverything is an Object• Examining some builtin classes• All these are classes in Squeak
Object Class Method ,Block files, editors, compilers, tools Boolean
TrueFalse
• Run time type information• Implementation of new• Printing objects
03G-2
Learning SqueakLearning SqueakThe best way to learn Squeak is to explore the definitions of builtin classes. A file containing the implementation of any class may be produced by clicking File Out on a class or an entire category.
The result is a file containing smalltalk code
Such files can be Filed In usingthe file list browser.
03G-3
The Class ObjectThe Class Object• The class Object is the rootroot of Squeak’s hierarchy.
• It inherits from ProtoObject, but we currently ignore this class
• Most other classes inherits from it, directly or indirectly.• The existence of a single root is useful to assure that
some messages are understood by any object.• Object defines about 400 methods
• The methods defined in the class Object may be: Used to define a common behaviour. These methods need not
be overridden. Their implementation is based on other methods. Used to provide a default behaviour. These methods should be
overridden by subclasses when appropriate.
• Some methods are implemented by calling primitivesprimitives. A primitive is a kind of external function.
• The class Object is an Abstract ClassAbstract Class. Question: What is the superclass of ProtoObject?
03G-4
ObjectsObjects’’ Printability Printability• The method printString provides a common
behaviour. Its implementation is based on the method printStringLimitedTo: which is based on printOn:.
printString^ self printStringLimitedTo: 50000
printStringLimitedTo: t1 | t2 |t2 := String streamContents:
[:t3 | self printOn: t3]limitedTo: t1.
t2 size < t1ifTrue: [^ t2].
^ t2 , '...etc...‘
03G-5
ObjectsObjects’’ Printability – Cont. Printability – Cont.The method printOn:provides a default behaviour. The
default is returning the name of the receiver’s class.printOn: t1
| t2 |t2 := self class name.t1
nextPutAll: (t2 first isVowelifTrue: ['an ']ifFalse: ['a ']);
nextPutAll: t2
The method class is implemented by a primitive.class
<primitive: 111>self primitiveFailed
Override printOn: to give your objects a sensible textualrepresentation
03G-6
Fraction >>PrintOn:Fraction >>PrintOn:printOn: aStream
aStream nextPut: $(.numerator printOn: aStream.aStream nextPut: $/.denominator printOn: aStream.aStream nextPut: $).
03G-7
Equality TestsEquality TestsThe method == of ProtoObject returns true if the
receiver and argument are the same object. It is implemented by a primitive.
== t1 <primitive: 110>self primitiveFailed
The method ~~ is based on ==. It needs not be overridden.~~ t1
self == t1ifTrue: [^ false].
^ trueThe method = returns true if the receiver and argument
are objects with the same value. It must be overridden.= t1 ^ self == t1
03G-8
CollectionCollection’’s Equalitys Equality• The class SequenceableCollection overrides the
method == t1
self == t1ifTrue: [^ true].
self species == t1 speciesifFalse: [^ false].
^ self hasEqualElements: t1
SequenceableCollection provides a default behaviour that is more appropriate for its subclasses
• The method = in class Complex= anObject
anObject isNumber ifFalse: [^false].anObject isComplex
ifTrue: [^ (real = anObject real) & (imaginary = anObject imaginary)]
ifFalse: [^ anObject adaptToComplex: self
andSend: #=]]
03G-9
Copying ObjectsCopying Objects• The method shallowCopy returns a copy of the
receiver. a shallow copy of an object shares its references to instance
variables with the original object.• The method shallowCopy provides common behaviour, based
on methods basicSize and basicAt:, which are implemented by primitives.
• The method copyTwoLevel copies also first level of instance variables• i.e, makes a shallow copy of each variable
• The method deepCopy copies also all of the objects within the receiver, recursively. It must be overridden.
Bug: deepCopy will not terminate when applied to a mutually recursive structure:
03G-10
Copy – Cont.Copy – Cont. The method copy may be either a shallow or a
deep copy, depending upon what is appropriate for the receiver.
copy^self shallowCopy postCopy
Override postCopy to copy any instance variables that should not be shared.
03G-11
Copy in DictionaryCopy in DictionaryThe class Dictionary overrides the method copy.
copy^ self shallowCopy
withArray: (array collect: [:t1 | t1 ifNotNil:
[Association key: t1 key value: t1 value]])
03G-12
Objects in SqueakObjects in Squeak Everything is an object
Things only happen by message passing Variables are dynamically bound
State is private to objects Encapsulation boundary is the object “protected” for subclasses
Methods are public “private” methods by convention only
(Nearly) every object is a reference Unused objects are garbage-collected
Single inheritance
03G-13
Squeak’s Object ModelSqueak’s Object Model Rule 1: Everything is an object.
Integers are objects3 + 4 "send '+ 4' to 3, yielding 7"20 factorial "send factorial, yielding a big number"
Classes are objects Rule 2: Every object is an instance of a class.
A class specifies the structure and behaviour of its instances Instances of a class share the same behavior and have a specific
state The class of an object can be obtained by sending it the class message
1 class -> SmallInteger20 factorial class -> LargePositiveInteger'hello' class −> ByteString#(1 2 3) class −> Array(4@5) class −> PointObject new class −> Object
03G-14
Squeak’s Object Model - contSqueak’s Object Model - cont Rule 3: Every class has a superclass.
Each class inherits its behaviour and the description of its structure from a single superclass.
SmallInteger superclass −> IntegerInteger superclass −> NumberNumber superclass −> MagnitudeMagnitude superclass −> ObjectObject superclass −> ProtoObjectProtoObject superclass −> nil
Rule 4: Everything happens by message sends. Rule 5: Method lookup follows the inheritance chain.
The class of the receiver looks up the method to handle the message. If this class does not have a method, it asks its superclass, and so on,
up the inheritance chain. If method is not found, the object sends
self doesNotUnderstand: #<message name>.
03G-15
Metaclasses in 7 pointsMetaclasses in 7 points1. Every object is an instance of a class2. Every class eventually inherits from Object3. Every class is an instance of a metaclass4. The metaclass hierarchy parallels the class
hierarchy5. Every metaclass inherits from Class and
Behavior6. Every metaclass is an instance of Metaclass7. The metaclass of Metaclass is an instance of
Metaclass
03G-16
Every class is an instance of a metaclassEvery class is an instance of a metaclass Classes are objects too!
Each class X is the unique instance of its metaclass, called X class
Object
Magnitude
Number
anInteger
Integer class
Number class
Integer
Magnitude class
Object class
Instance of
03G-17
MetaclassesMetaclasses Metaclasses are implicit
There are no explicit metaclasses Metaclasses are created implicitly when classes are
created No sharing of metaclasses (unique metaclass per
class) Metaclasses are anonymous
Can be referred to through the class that is their instance
Integer class Integer class Object class Object class
03G-18
The metaclass hierarchy parallels the The metaclass hierarchy parallels the class hierarchyclass hierarchyObject
Magnitude
Number
anInteger
Integer class
Number class
Integer
Magnitude class
Object class
Instance of
03G-19
Every metaclass inherits from Class and Every metaclass inherits from Class and BehaviorBehavior
Object
Magnitude
Number
anIntegerInteger class
Number class
Integer
Magnitude class
Object class
Instance of
Class
ClassDescription
Behaviour
03G-20
Every metaclass is an instance of Every metaclass is an instance of MetaclassMetaclass
Object
Magnitude
Number
anInteger
Integer class
Number class
Integer
Magnitude class
Object class
Instance of
Class
ClassDescription
Behaviour
Metaclass
03G-21
Every metaclass is an instance of Every metaclass is an instance of MetaclassMetaclass
Object
Magnitude
Number
anInteger
Integer class
Number class
Integer
Magnitude class
Object class
Instance of
Class
ClassDescription
Behaviour
Metaclass
Metaclass class
03G-22
Inheritance
Instance of
03G-23
Class AttributesClass Attributes• Some of the attributes of any class are:
a name a superclass a set of methods a set of instance variables the instance size
• Additionally, classes have behaviour, which is defined by the methods implemented in the class side of a class
• The most important method is the one that makes the class able to generate new instances.
• When the message new is sent to a class• it is looked up in its metaclass chain and ultimately
in its superclass: Behavior
03G-24
The Method NewThe Method Newo The method new is first defined in the class Behavior,
and can be redefined in its subclasses, including any metaclass of classes we define.o new always returns an instance of self, the class that receives
the message, even if it is implemented in another class.o new first creates a new instance and then sends to it the
message initialize:new
^ self basicNew initializeo basicNew allocates an instance using a primitive.o new is redefined in Metaclass:new
thisClass class ~~ selfifTrue: [^ thisClass := self basicNew].self error:
'A Metaclass should only have one instance!'
03G-25
Method LookupMethod LookupTwo step process:
Lookup starts in the class of the receiver (an object)
1.If the method is defined in the method dictionary, it is used
2.Else, the search continues in the superclass If no method is found, this is an error …
03G-26
Looking for MethodsLooking for Methods• respondsTo: is defined in Object as:respondsTo: t1
^ self class canUnderstand: t1• canUnderstand: is defined in Class as:canUnderstand: t1
(self includesSelector: t1)ifTrue: [^ true].
superclassifNil: [^ false].
^ superclass canUnderstand: t1
03G-27
Run-Time Type InformationRun-Time Type Information• Since Smalltalk is dynamically typeddynamically typed it is useful to ask
about the identity of the objects.• The methods isMemberOf: and isKindOf: defined in
Object may be used for type checking.
isMemberOf: t1 ^self class == t1
isKindOf: t1 self class == t1
ifTrue: [^ true].^ self class inheritsFrom: t1
03G-28
Design TechniquesDesign Techniques• The builtin classes of Squeak provide several examples
of design techniquesdesign techniques that are characteristic of Object Oriented Programming.
• Some of these techniques are: Providing additional functionality using composite composite
methodsmethods, implemented over basic ones. Example: The reject: class Collection.
The use of abstract classesabstract classes implementing the common behavior of its subclasses. Example: The classes Boolean, True and False.
03G-29
Composite MethodsComposite Methods• A class should provide to its clients all the functionality
that may be usefuluseful, even if not absolutely necessary.• The protocol of a class may be extendedextended by the addition
of composite methods, implemented over basic ones.• The implementation of these additional methods
requires very little effortlittle effort, but makes the class more powerful.
• The main advantages of composite methods are: The interface of the class becomes more abstractabstract. The protocol of the class becomes more completecomplete. The class becomes more useful. The class becomes easier to use.
Composite methods improve reusabilityreusability.
03G-30
The Class CollectionThe Class CollectionThe basicbasic method select: is used to implement the compositecomposite methods reject:select: aBlock | newCollection |
newCollection := self species new.self do: [:each | (aBlock value: each) ifTrue:
[newCollection add: each]].^newCollection
reject: t1 ^ self
select: [:t2 | (t1 value: t2) == false]
03G-31
Abstract ClassesAbstract Classes• Abstract classes are normally derived by the
generalizationgeneralization of its subclasses.• They provide a common behaviorcommon behavior for their
subclasses.• The methods implemented by an abstract class are
normally compositecomposite. The basic methods should be provided by the subclasses.
• The main advantages of abstract classes are: Provide a common protocol for the subclasses. Avoid several implementations of the same
methods. Allow new subclasses to be derived without
having to reimplement all the functionality.• The methods implemented in an abstract class are
reusedreused by its subclasses.
03G-32
The Class BooleanThe Class BooleanThe class Boolean is an abstract class:
ifTrue: t1 self subclassResponsibility
!!ifFalse: t1
self subclassResponsibility!!ifTrue: t1 ifFalse: t2
self subclassResponsibility!!ifFalse: t1 ifTrue: t2
self subclassResponsibility
03G-33
The Class TrueThe Class TrueThe class True inherits the functionality of Boolean.
ifTrue: t1 ^ t1 value
!!ifFalse: t1
^ nil!!ifTrue: t1 ifFalse: t2
^ t1 value!!ifFalse: t1 ifTrue: t2
^ t2 value
03G-34
The Class FalseThe Class FalseThe class False inherits the functionality of Boolean.
ifTrue: t1 ^ nil
!!ifFalse: t1
^ t1 value!!ifTrue: t1 ifFalse: t2
^ t2 value!!ifFalse: t1 ifTrue: t2
^ t1 value
03G-35
The Class BooleanThe Class BooleanTaken from Little Smalltalk, could be applied in SqueakTaken from Little Smalltalk, could be applied in Squeak
Class Boolean ObjectMethods Boolean ifTrue: trueBlock ^self ifTrue: trueBlock ifFalse: []| ifFalse: falseBlock ^self ifTrue: [] ifFalse: falseBlock| ifFalse: falseBlock ifTrue: trueBlock ^self ifTrue: trueBlock ifFalse: falseBlock| and: aBlock ^self ifTrue: aBlock ifFalse: [ false ]| or: aBlock ^self ifTrue: [ true ] ifFalse: aBlock]
03G-36
The Class TrueThe Class TrueTaken from Little Smalltalk, could be applied in SqueakTaken from Little Smalltalk, could be applied in Squeak
Class True BooleanMethods True ifTrue: trueBlock ifFalse: falseBlock ^trueBlock value| not ^false| xor: aBoolean ^aBoolean not| printString ^'true']
03G-37
The Class FalseThe Class FalseTaken from Little Smalltalk, could be applied in SqueakTaken from Little Smalltalk, could be applied in Squeak
Class False BooleanMethods False ifTrue: trueBlock ifFalse: falseBlock ^falseBlock value| not ^true| xor: aBoolean ^aBoolean| printString ^'false']