SDSU CS 535 Object-Oriented Programming
Fall Semester, 2003
Classes part 2
Previous    Lecture Notes Index    Next    
© 2003, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 04-Sep-03

Contents of Doc 4, Classes part 2



References

Ralph Johnson's University of Illinois, Urbana-Champaign CS 497 lecture notes, http://st-www.cs.uiuc.edu/users/cs497/

Smalltalk Best Practice Patterns, Beck

Reading

VisualWorks Application Developer’s Guide, Chapter 2 and 4. The VisualWorks Application Developer’s Guide is the file AppDevGuide.pdf in the docs directory of the VisualWorks directory. On Rohan this file is /opt/vw71nc/doc/AppDevGuide.pdf

(Beck) Chapter 6 - Classes pp 167-170
(Beck) pp 23-27, 39, 48-51, 59-64

Doc 4, Classes part 2 Slide # 2

Objects & Classes - Smalltalk Language Details


Items to cover:

Class names

Methods



Inheritance

self & super

Doc 4, Classes part 2 Slide # 3

Class Names


Smalltalk class names:

Names are read 100 to 1000 times more often than typed
Abbreviations waste more time (reading) than they save
SmallInteger, LimitedWriteStream, LinkedMessageSet



Doc 4, Classes part 2 Slide # 4

Simple Superclass Name


Superclass names


Number
Collection
Magnitude
Model


Doc 4, Classes part 2 Slide # 5

Qualified Subclass Name


If name is in common use
Array, Number, String
If the purpose is more important that class hierarchy
If the class hierarchy is important
Subclass is conceptually a variation on the superclass
OrderedCollection, LargeInteger, CompositeCommand


Doc 4, Classes part 2 Slide # 6

Class Names & Namespaces



Classes are defined in a namespace

Allows classes in different namespaces to use the same name

Full name of a class includes namespace

Root.Smalltalk.Core.Point is full name of Point class


The import mechanism allows one to use shorter names

Workspace windows import all namespaces


Doc 4, Classes part 2 Slide # 7
Point Name Example

Each of the following is legal code in a workspace

 Root.Smalltalk.Core.Point 
      x: 1
      y: 1.
 Smalltalk.Core.Point 
      x: 1
      y: 1.
 Core.Point 
      x: 1
      y: 1.
 Point 
      x: 1
      y: 1.



Doc 4, Classes part 2 Slide # 8

Methods


All methods are public

Methods considered private are placed in the method category called "private"

All methods return a value


Doc 4, Classes part 2 Slide # 9

Instance methods


Sent to instances of Classes

Examples
1 + 2
'this is a string' reverse


Doc 4, Classes part 2 Slide # 10

Class methods


Sent to Classes

Can not be sent directly to instance of the class

Commonly used to create instances of the class

Examples

Point new
Point x: 1 y: 3
Float pi


Doc 4, Classes part 2 Slide # 11
Indicating the class of a methodSmalltalk Convention


ClassName>>methodName


String>>reverse

Point class>>x:y:


Doc 4, Classes part 2 Slide # 12

Variables

Types of Variables



Doc 4, Classes part 2 Slide # 13

Temporary (Local) Variable


Must be declared at the beginning of a method or “program”

| a b sum | 
a := 5.
b := 10.
sum := a + b.




Point>>grid: aPoint 
   "Answer a new Point to the nearest rounded grid modules 
   specified by aPoint."
   | newX newY |
   aPoint x = 0
      ifTrue:   [newX := 0]
      ifFalse:   [newX := x roundTo: aPoint x].
   aPoint y = 0
      ifTrue:   [newY := 0]
      ifFalse:   [newY := y roundTo: aPoint y].
   ^newX @ newY


Doc 4, Classes part 2 Slide # 14

Named Instance Variable

Each object has its own copy of a named instance variable

Like
Protected C++ data member
Protected Java field)

Accessible by
Instance methods of the class
Instance methods of subclasses of the class
Not accessible by
Methods in non-subclasses
Class methods


Doc 4, Classes part 2 Slide # 15
Example

Smalltalk.Core defineClass: #Point
   superclass: #{Core.ArithmeticValue}
   indexedType: #none
   private: false
   instanceVariableNames: 'x y '
   classInstanceVariableNames: ''
   imports: ''
   category: 'Graphics-Geometry'

x & y are instance variables

| a b | 
a := Point 
   x: 1 
   y: 4.
b := Point 
   x: -1 
   y: 2.
We now have two point objects. Each point object has a local copy of x and y. Values in the local copies are different.


Doc 4, Classes part 2 Slide # 16
Accessing Instance variables in an Instance method

Point instance method example

Point>>dotProduct: aPoint 
   ^(x* aPoint x) +  (y * aPoint y)

Doc 4, Classes part 2 Slide # 17
Adding an Instance Variables to a Class

To add an instance variable to a class,

Add the variable name in the string argument of instanceVariableNames:

Example

To add a z to the point class, just add z to the string
Smalltalk.Core defineClass: #Point
   superclass: #{Core.ArithmeticValue}
   indexedType: #none
   private: false
   instanceVariableNames: 'x y z '
   classInstanceVariableNames: ''
   imports: ''
   category: 'Graphics-Geometry'


Doc 4, Classes part 2 Slide # 18
Removing an Instance Variables to a Class

Remove the variable name from the class definition

Make sure no methods still use the variable


Doc 4, Classes part 2 Slide # 19

Class Instance Variable

A class has one instance
Each subclass has a different instance
Accessible by
Class methods
Class methods of subclasses

Doc 4, Classes part 2 Slide # 20
ExampleClass Definitions
Smalltalk.Core defineClass: #ClassInstanceVariableExample
   superclass: #{Core.Object}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: 'test '
   imports: ''
   category: 'As yet unclassified'

ClassInstanceVariableExample class>>test
   test isNil ifTrue:[ test := 0].
   test := test + 1.
   ^test

Smalltalk.Core defineClass: #ClassInstanceVariableChild
   superclass: #{Core.ClassInstanceVariableExample}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: ''
   category: 'As yet unclassified'

Doc 4, Classes part 2 Slide # 21
The Test
ClassInstanceVariableExample test.
Transcript 
   print: ClassInstanceVariableExample test;
   cr;
   print: ClassInstanceVariableChild test;
   cr;
   flush
Output in Transcript
2
1

Doc 4, Classes part 2 Slide # 22

Shared Variables


Only one copy exists of each shared variable

Multiple classes and object can access the same shared variable


Doc 4, Classes part 2 Slide # 23
Adding a Shared Variable to a Class

In a browser select an existing class.

Click on the "shared variables" radio button in the browser

Now use the "Protocol" menu to add a new category for the shared variables

You get the template

SharedVariableClass defineSharedVariable: #NameOfBinding
   private: false
   constant: false
   category: 'accessing'
   initializer: 'Array new: 5'
Change NameOfBinding to the name of the variable

Keep the "#" before the name

Change the other values as appropriate



Doc 4, Classes part 2 Slide # 24
Private and Public Shared Variables

A shared variable can be accessed from any class

Private shared variable access

In the class just use short name of the variable
Outside the class use the fully qualified name


Public shared variable access

In the class & subclasses use short name
Outside the class
Use fully qualified name or
Use import to shorten the name

Private does not seem to be the correct term

Doc 4, Classes part 2 Slide # 25
Example
Smalltalk.Core defineClass: #SharedVariableExample
   superclass: #{Core.Object}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'

Core.SharedVariableExample defineSharedVariable: #PublicVariable
   private: false
   constant: false
   category: 'data'
   initializer: '3'

Core.SharedVariableExample defineSharedVariable: #PrivateVariable
   private: true
   constant: false
   category: 'data'
   initializer: '5'

SharedVariableExample Instance Methods

privateVariable
   ^PrivateVariable

privateVariable: anObject
   PrivateVariable := anObject

publicVariable
   ^PublicVariable

publicVariable: anObject
   PublicVariable := anObject 


Doc 4, Classes part 2 Slide # 26
Subclass Accessing Shared Variables

Smalltalk.Core defineClass: #SharedVariableChild
   superclass: #{Core.SharedVariableExample}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'

Core.SharedVariableChild methodsFor: 'accessing'

childPublic
   ^PublicVariable 

childPrivate
   "Subclass can not use short name on private"
   ^Core.SharedVariableExample.PrivateVariable


Doc 4, Classes part 2 Slide # 27
Other Class Accessing Shared Variables

Smalltalk.Core defineClass: #SharedVariableUser
   superclass: #{Core.Object}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: '
         Core.SharedVariableExample.*
         '
   category: 'Course-Examples'

Core.SharedVariableUser methodsFor: 'accessing'

privateVariable
   "Can not use short name on private variables"

   ^Core.SharedVariableExample.PrivateVariable


publicVariable
   ^PublicVariable 


Doc 4, Classes part 2 Slide # 28
Initializing Shared Variables

Core.SharedVariableExample defineSharedVariable: #PublicVariable
   private: false
   constant: false
   category: 'data'
   initializer: '3'

Shared variables have an initializer

The initializer by:

#{Core.SharedVariableExample.PublicVariable} initialize


Doc 4, Classes part 2 Slide # 29
Constant Verses Non-Constant Shared Variables

A constant shared variable's value:



Non-constant shared variable's value can changed

Core.SharedVariableExample.PublicVariable := 42.


Doc 4, Classes part 2 Slide # 30
Some Existing Uses of Shared Variables

Transcript

A shared variable

An object that writes to a window


Character Constants

Where are tab, space, cr, lf defined?

Solution one - Class methods of Character

Character cr
Character space
Character lf

Works, but is verbose
Solution Two - Shared Variables

Graphics.TextConstants defines shared variables
Tab, CR, LF, Space
To use in a class import "Graphics.TextConstants.*"


Doc 4, Classes part 2 Slide # 31

Indexed Instance Variable


Provides slots in objects for array like indexing

Used for Arrays

I have never added indexed instance variables

I have always used existing collection classes

Doc 4, Classes part 2 Slide # 32
Adding Indexed Instance Variables to a Class

Create a class using Class:Add Class:Indexed menu item in the browser.



You get the template somewhat like:

Core defineClass: #NameOfClass
   superclass: #{NameOfSuperclass}
   indexedType: #objects
   private: false
   instanceVariableNames: 'instVarName1 instVarName2'
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'


Doc 4, Classes part 2 Slide # 33
For this example I edited the template to be:

Core defineClass: #IndexedExample
   superclass: #{Core.Object}
   indexedType: #objects
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'


Once this is saved the following works:

| a |
a := IndexedExample new: 10.
a 
   at: 1 put: 2.
^a


Doc 4, Classes part 2 Slide # 34

Inheritance


Smalltalk supports only single inheritance

Each class has single parent class

A class inherits (or has) all
Methods defined in its parent class
Methods defined in its grandparent class
etc.
Methods defined in any ancestor class
Variables defined in any ancestor class

Some Terminology

Parent Class
Superclass
Base Class
Mean same thing

Child class
Subclass
Derived class
Mean the same thing


Doc 4, Classes part 2 Slide # 35
Class "Object"





Doc 4, Classes part 2 Slide # 36
Inheritance and Name Clashes

Subclass can implement methods with same name as parent

This is called overloading the method

When message is sent to instance of the subclass, the subclass method is used


Subclass can not overload variable names



Doc 4, Classes part 2 Slide # 37

Special or PseudoVariables


self
Refers to the receiver of the message (current object)
Methods referenced through self are found by:
Searching the class hierarchy starting with the class of receiver
super
Refers to the receiver of the message (current object)
Methods referenced through super are found by:
Searching the class hierarchy starting the superclass of the class containing the method that references super

Called pseudo-variables because:

They do change value
You can not assign values to them


Doc 4, Classes part 2 Slide # 38
Self, Super Example

Three classes to study self & super: Parent, Child, GrandChild

Parent

Smalltalk.Core defineClass: #Parent
   superclass: #{Core.Object}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'

Instance Methods

name
   ^'Parent' 


Doc 4, Classes part 2 Slide # 39
Child
Smalltalk.Core defineClass: #Child
   superclass: #{Core.Parent}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'
Instance Methods
name
   ^'Child'

selfName
   ^self name

superName
   ^super name 

GrandChild
Smalltalk.Core defineClass: #GrandChild
   superclass: #{Core.Child}
   indexedType: #none
   private: false
   instanceVariableNames: ''
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'
GrandChild Instance Methods
name
   ^'GrandChild' 


Doc 4, Classes part 2 Slide # 40
Self, Super Example - ContinuedTest Program

|  grandchild |
Output In Transcript
grandchild := Grandchild new.

Transcript

   show: grandchild name;
Grandchild
   cr;

   show: grandchild selfName;
Grandchild
   cr;

   show: grandchild superName;
Parent
   cr.



Doc 4, Classes part 2 Slide # 41
Self, Super Example - ContinuedHow does this Work?

grandchild selfName
receiver is grandchild object

Code in selfName method is ^self name

To find the method self name start search in Grandchild class

grandchild superName

receiver is grandchild object

Code in superName method is ^super name

superName is implemented in Child class

To find the method self name start search in the superclass of Child


Doc 4, Classes part 2 Slide # 42
Why Super

Super is used when:

The child class extends the behavior of the inherited method

That is:


In this case super is needed access the inherited method


Doc 4, Classes part 2 Slide # 43
Why doesn't super refer to parent class of the receiver?

Object subclass #Parent

name
   ^'Parent' 


Parent subclass #Child

name
   ^super name , 'Child' 


Child subclass #Grandchild
"No methods in Grandchild"

Sample Program
| trouble |
trouble := Grandchild new.
trouble name.

Assume that super did refer to the parent class of the receiver. Sending the message "name" to trouble would call the code "super name , 'Child' ". The super would refer to the parent class of the receiver. Since the receiver is a Grandchild object, "super name" would refer to the "name" method in the Parent class. Hence the method will call itself with no way to end.


Doc 4, Classes part 2 Slide # 44

Implicit Return Values


If a method does not explicitly return a value, self is returned

Hence a method like:

decrease
   count ifNil: [count := 0].
   count := count - 1 

Is really:

decrease
   count ifNil: [count := 0].
   count := count - 1.
   ^self

Style Issue - When to explicitly return?

Only explicitly return a value from a method when the intent of the method is to return a value. An explicit return indicates to other programmers that the intent of the method is to compute some return value. The intent of the decrease method is to change the state of the receiver. Hence it should not have a value explicitly returned.


Doc 4, Classes part 2 Slide # 45

Initializing Instance Variables


If the instance variables always start at same value:


Smalltalk.Core defineClass: #Counter
   superclass: #{Core.Object}
   indexedType: #none
   private: false
   instanceVariableNames: 'count '
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'
Instance Methods

Category: initialize

initialize
   count := 0
Category: access

count
   ^count 

decrease
   count := count - 1 

increase
   count := count + 1 

Class Methods
Category: instance creation

new
   ^super new initialize


Doc 4, Classes part 2 Slide # 46
Example - Instance Creation with Parameters

Smalltalk.CS535 defineClass: #Counter
   superclass: #{Core.Object}
   indexedType: #none
   private: false
   instanceVariableNames: 'count '
   classInstanceVariableNames: ''
   imports: ''
   category: 'Course-Examples'
Instance Methods

Category: initialize

setCount: anInteger
   count := anInteger
Category: access

count
   ^count 

decrease
   count := count - 1 

increase
   count := count + 1 


Doc 4, Classes part 2 Slide # 47
Example - Instance Creation with Parameters ContinuedClass Methods

Category: instance creation

new
   ^self count: 0

count: anInteger
   ^super new setCount: anInteger

Category: examples

example
   "Counter example"   "or one can use self example"
   | a |
   a := Counter new.
   a
      increase;
      increase.
   ^a count


Doc 4, Classes part 2 Slide # 48
Class Methods that Create Instances

Some Guidelines [1]

Smalltalk does not have constructors like C++/Java

Use class methods to create instances

Place these class methods in "instance creation" category


Initial State of Instances

Create objects in some well-formed state

Class creation methods should:

Have parameters for initial values of instance variables or
Set default values for instance variables

Provide an instance method that:

Sets the initial values of instance variables
Place method in "initialize" or "initialize - release" category
Use the name setVariable1: value variable2: ...


Doc 4, Classes part 2 Slide # 49
Beck's First Rule of Good Style [2]

"In a program written with good style,
everything is said once and only once"


Some violations of the rule:



Example
new
   ^self count: 0

count: anInteger
   ^super new setCount: anInteger

Not

new
   ^super new setCount: 0

count: anInteger
   ^super new setCount: anInteger

If the logic of creating a new instance changes, the first version only has one place to change.


Doc 4, Classes part 2 Slide # 50
Providing Examples in Class Methods

A common Smalltalk practice is to provide



Place such example methods in "example(s)" category


Category: examples

example
   "Counter example"
   | a |
   a := Counter new.
   a
      increase;
      increase.
   ^a count
 

Doc 4, Classes part 2 Slide # 51
[1] See Beck 1997, Constructor Method and Constructor Parameter Method patterns, pp. 21-24 and Johnson's class notes on Smalltalk Coding Standards
[2] See Beck 1997, page 6

Copyright ©, All rights reserved.
2003 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 04-Sep-03    Next