Object Orientation James Brucker
Smalltalk • Ahead of its time: consistent design and rich library. • Dynamic (like Lisp): variables have no specified type. • The class structure is the type system. • Everything is an object, including numbers. So somewhat lacking in efficiency. • There are no explicit protection markers: all data is implicitly private, all methods implicitly public. • Syntax is peculiar, and tied to the runtime environment. • Typically only a global namespace for classes, so I will call the example class MyPoint.
Smalltalk MyPoint class • Using the syntax conventions of the text:Class name: MyPointSuperclass: ObjectInstance variables: x y "(data fields)"Methods: getX x getY y moveBy: dx and: dy x x + dx. y y + dy toString (super asString),'[x=',x asString,',y=', y asString,']' • Note lack of constructors (see later slide). • Special characters: = return, = assignment.
Smalltalk MyPoint class comments • Note definition of moveBy:moveBy: dx and: dyMethods that take arguments must have a name ending in a colon (a keyword selector) before every argument. So this method is actually the moveBy:and: method. • The period in the moveBy:and: code is like a semicolon—it separates (not terminates) statements. • Note use of asString in code for toString. Indeed, we should really call this method asString too. • The comma in the toString code is the string concatenation operator, and single quotes delimit string literals.
Smalltalk MyPoint constructors • Constructors in Smalltalk are class methods: they are sent to the class (which is an object). • There is a predefined constructor named new (with no arguments—like the default constructor), which initializes all instance variables to nil. • new can be redefined (but probably shouldn't), and any other class methods can also be added. • To avoid these complications (and some others not mentioned), we add two initialize methods (which is a standard hack):initialize x 0. y 0 initialize: x0 and: y0 x x0. y y0
Smalltalk MyPoint driver • I/O is another problem area in Smalltalk, since all execution occurs inside windows, and typically we would have to create a new window to see output. • Inside a workspace (code to execute), all values can be inspected, and we will use this to see the output. • Here is the driver workspace code:p MyPoint new initialize: 1 and: 2.p inspect.p toString inspect.p moveBy: 1 and: 1.r p getX + p getY.r inspect • The result in a typical Smalltalk system (Squeak) is on the next slide.
Smalltalk ColoredPoint class Class name: ColoredPointSuperclass: MyPointInstance variables: colorMethods: getColor color setColor: c0 color c0 initialize super initialize. color Color white initialize: x0 and: y0 super initialize: x0 and: y0. color Color white initialize: x0 and: y0 and: c0 super initialize: x0 and: y0. color c0 toString (super toString),'[color=',color asString,']'
Smalltalk ColoredPoint, cont'd. • Note calls to super in the previous slide. • Although we don't use it, the this reference is called self in Smalltalk. • Now we change the first line of the driver code to:p ColoredPoint new initialize: 1 and: 2. • Running the driver code produces the picture on the next slide. • Note that, as expected, the result of the toString method changes from'a MyPoint[x=1,y=2]'to'a ColoredPoint[x=1,y=2][color=Color white]'
OO Implementation Issues • Efficiency is a concern since dynamic binding appears to imply a search of the class hierarchy at each call site. • Smalltalk in fact does this. • Runtime penalty can be mitigated by hashing and extra links. But still significant. • Better: compute method table for each class at compile time, with statically fixed offsets for each method. Assign a pointer to it on object creation. Then follow the pointer (one extra indirection plus an offest calculation) at each call site. • Variously named VMT, VFT, or just method table (V for virtual).