SDSU CS 535 Object-Oriented Programming
Fall Semester, 2003
Abstract Classes, Inheritance & Testing
Previous    Lecture Notes Index    Next    
© 2003, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 21-Oct-03

Contents of Doc 14, Abstract Classes, Inheritance & Testing



References
Object-Oriented Design Heuristics, Riel
łA Short Catalog of Test Ideas˛ by Brian Marick, http://www.testing.com/writings.html

Reading

Object-Oriented Design Heuristics, Chapter 2.


Doc 14, Abstract Classes, Inheritance & Testing Slide # 2

Abstract Classes


Abstract class – a class not used to create instances of itself

Concrete class – a class that we do create direct instances of


Why Abstract Classes



Doc 14, Abstract Classes, Inheritance & Testing Slide # 3
Defining an Abstract Class

Some languages have special syntax for abstract classes

public abstract  class  NoObjects  {
   public  void  aFunction()  {
      System.out.println(  "Hi Mom"  );
   }
   public  abstract  void  subClassMustImplement(  int  foo  );
} 


Smalltalk does not have special syntax for abstract classes



      Collection>>do: aBlock
          self subclassResponsibility




Doc 14, Abstract Classes, Inheritance & Testing Slide # 4
What does self subclassResponsibility do?

Inform reader

Raises an exception when executed to indicate




Doc 14, Abstract Classes, Inheritance & Testing Slide # 5
How to Prohibit Instances of Abstract Class


Documentation is normally enough


Implement new so it throws an exception

Stream class>>new
   "Provide an error notification that Streams are not created
   using this message."
   self error: ('Streams are created with on: and with:')



Doc 14, Abstract Classes, Inheritance & Testing Slide # 6
How do subclass objects get created?

PositionableStream is a subclass of Stream

PositionableStream class>>on: aCollection
   ^super new on: aCollection   “Throws and Exception”
Use basicNew

PositionableStream class>>on: aCollection
   ^self basicNew on: aCollection   


basicNew




Doc 14, Abstract Classes, Inheritance & Testing Slide # 7
Some Collection Classes


(N) indicates number of methods defined the class

Bold indicates concrete classes


Doc 14, Abstract Classes, Inheritance & Testing Slide # 8
Abstract Classes and Data


Abstract classes commonly do not have instance variables

How can they implement methods?


Identify a core set of abstract operations

Implement other methods using core methods


Doc 14, Abstract Classes, Inheritance & Testing Slide # 9
Collection Class

Collection does not have any instance variables

Collection implements

All are defined in terms of do:

Collection>>detect: aBlock ifNone: exceptionBlock 
   self do: [:each | (aBlock value: each) ifTrue: [^each]].
   ^exceptionBlock value


Collection>>do: aBlock
    self subclassResponsibility


Subclass just implements do: the rest will work

All the above enumerations work on your BinarySearchTree


Doc 14, Abstract Classes, Inheritance & Testing Slide # 10
Abstract Classes, Types and Hinges

Tagging (declaring) a variable to be an Abstract class instance




SomeClass>>foo: aCollection
   ^aCollection fold: [:a :b | a max: b].

public class SomeClass {
   public int foo(Collection a) { blah}
}

public class Resticted {
   public int foo(Array a) { blah}
}


Doc 14, Abstract Classes, Inheritance & Testing Slide # 11
Abstract Classes and Hiding



Smalltalk VM on startup informs Filename of the correct concrete class for the current platform

‘foo’ asFilename
Filename named: ‘foo’

Create an instance of the correct concrete Filename class


Doc 14, Abstract Classes, Inheritance & Testing Slide # 12
Platform Independence Aside

End of line Characters

Mac, PC and Unix have different end of line characters

When you read a file:



When you write a file



Same code


Doc 14, Abstract Classes, Inheritance & Testing Slide # 13

Abstract Classes and Hiding



String is an abstract class

String new

String subclasses


Doc 14, Abstract Classes, Inheritance & Testing Slide # 14
Strings Continued

| a |
a :=String new.
a class.              "returns ByteString"

| b | 
b :=(String with: (Character value: 3585)) "3585 is Thai character".
b class             "returns TwoByteString"

| c |
c := String with: $a.
c class.             “returns ByteString”
c at: 1 put:  (Character value: 3585).
c class             “returns TwoByteString”

To learn about character encodings read:
http://www.joelonsoftware.com/articles/Unicode.html


Doc 14, Abstract Classes, Inheritance & Testing Slide # 15
become: Smalltalk Magic

| c |
c := String with: $a.
c class.             “returns ByteString”
c at: 1 put:  (Character value: 3585).
c class             “returns TwoByteString”


How did c change class?


a become: b





Doc 14, Abstract Classes, Inheritance & Testing Slide # 16
String Transformation without become?

Use composition

String has instance variable that holds real string

String forwards messages to the real string

String can replace the real string with a different object

Smalltalk.Core defineClass: #String
   superclass: #{Core.CharacterArray}
   indexedType: #none
   private: false
   instanceVariableNames: 'realString'
   classInstanceVariableNames: ''
   imports: ''
   category: 'Collections-Text'

size
   ^realString size

at: anInteger
   ^realString at: anInteger

at: anInteger put: aCharacter
   aCharacter value > 256 
      ifTrue: [realString := realString atTwoByteString].
   realString at: anInteger put: aCharacter.


Doc 14, Abstract Classes, Inheritance & Testing Slide # 17

Inheritance


What should I use as a super class?



Indicates that an instance variable of A is an instance of B



Indicates that A is a subclass of B


A car has an engine, so car object contains an engine object

A BinarySearchTree has nodes, so it has instance variables left and right

A WordStream is a type of ReadStream so it is a subclass of ReadStream


Doc 14, Abstract Classes, Inheritance & Testing Slide # 18
Common Mistakes

Engine Subclass of Car



Using a has-a relation for inheritance

Car subclass of Engine



“I need access to engine methods in the car class and now I have it.”

Doc 14, Abstract Classes, Inheritance & Testing Slide # 19
Roles Verses Classes

2.11 Be sure the abstractions you model are classes and not simply the roles objects play


BinarySearchTree>>initialize
left := LeftNode new.
right := RightNode new.



BinarySearchTree>>initialize
left := Node new.
right := Node new.


Doc 14, Abstract Classes, Inheritance & Testing Slide # 20



initialize
   mother := Mother new.
   father := Father new.
etc.

initialize
   mother := Person new.
   father := Person new.
etc.


Doc 14, Abstract Classes, Inheritance & Testing Slide # 21

What to Test


Everything that could possibly break

How often do accessor methods have errors?

Node>>value
   ^value

How many errors did your WordStream>>next method have?


Doc 14, Abstract Classes, Inheritance & Testing Slide # 22
Some Guidelines

Test values



GUIs are very hard to test



Doc 14, Abstract Classes, Inheritance & Testing Slide # 23
Common Things that Programs Handle Incorrectly

Adapted with permission from “A Short Catalog of Test Ideas” by Brian Marick, http://www.testing.com/writings.html


Strings

Test using empty String

Collections

Test using:

Numbers

Test using:


Doc 14, Abstract Classes, Inheritance & Testing Slide # 24
Do we need to test all methods?

Character>>isWordSeparator
   ^self isSeparator | (#($, $. $; $' $" $? $!) includes: self)

Character>>dollarValue
   self isAlphabetic ifFalse:[^0].
   ^self asLowercase asInteger - $a asInteger + 1

String>>dollarValue
   ^self inject: 0 into: [:subTotal :next | subTotal + next dollarValue]

String>>words
   ^self runsFailing: [:each | each isWordSeparator]

String>>dollarWords
   ^self words select: [:each | each dollarValue = 100]
Can we just test String>>dollarWords?

If String>>dollarWords works correctly then all the other methods are highly likely to also work correctly

Benefit

Drawbacks


Doc 14, Abstract Classes, Inheritance & Testing Slide # 25
Can we just test

String>>dollarValue
String>>words

If these methods work what could be wrong with String>>dollarWords?



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 21-Oct-03    Next