The Visitor Pattern
Slide Annotated slide Contents Index
References 

The transition from the natural object-oriented solution to the visitor solution

Not in use - for exercise
Slide Annotated slide Contents Index
References 

Program: A die class for an IO exercise.
using System;

public class Die {
  private int numberOfEyes;
  private Random randomNumberSupplier; 
  private const int maxNumberOfEyes = 6;

  public Die(){
    randomNumberSupplier = Random.Instance();
    numberOfEyes = NewTossHowManyEyes();
  }   
    
  public void Toss(){
    numberOfEyes = NewTossHowManyEyes();
  }

  private int NewTossHowManyEyes (){
    return randomNumberSupplier.Next(1,maxNumberOfEyes + 1);
  }

  public int NumberOfEyes() {
    return numberOfEyes;
  }

  public override String ToString(){
    return String.Format("[{0}]", numberOfEyes);
  }
}

public class Random {

  // Singleton pattern:
  // Keeps track of unique instance of this class
  private static Random uniqueInstance = null;

  // Holds the instance of System.Random
  private System.Random systemRandom;

  // Singleton pattern: Private constructor.
  private Random(){
    systemRandom = new System.Random(unchecked((int)DateTime.Now.Ticks));
  }

  public static Random Instance(){
    if (uniqueInstance == null)
      uniqueInstance = new Random();
    return uniqueInstance;
  }

  public int Next(int lower, int upper){
    // delegate to systemRandom
    return systemRandom.Next(lower,upper);
  }

}

Not in use - for exercise
Slide Annotated slide Contents Index
References 

Program: A die class for the Die comparison exercise.
using System;

public class Die {
  private int numberOfEyes;
  private Random randomNumberSupplier; 
  private const int maxNumberOfEyes = 6;

  public Die(){
    randomNumberSupplier = Random.Instance();
    numberOfEyes = NewTossHowManyEyes();
  }   
    
  public void Toss(){
    numberOfEyes = NewTossHowManyEyes();
  }

  private int NewTossHowManyEyes (){
    return randomNumberSupplier.Next(1,maxNumberOfEyes + 1);
  }

  public int NumberOfEyes() {
    return numberOfEyes;
  }

  public override String ToString(){
    return String.Format("[{0}]", numberOfEyes);
  }
}

public class Random {

  // Singleton pattern:
  // Keeps track of unique instance of this class
  private static Random uniqueInstance = null;

  // Holds the instance of System.Random
  private System.Random systemRandom;

  // Singleton pattern: Private constructor.
  private Random(){
    systemRandom = new System.Random(unchecked((int)DateTime.Now.Ticks));
  }

  public static Random Instance(){
    if (uniqueInstance == null)
      uniqueInstance = new Random();
    return uniqueInstance;
  }

  public int Next(int lower, int upper){
    // delegate to systemRandom
    return systemRandom.Next(lower,upper);
  }

}

Not in use - for exercise
Slide Annotated slide Contents Index
References 

Program: The class Set with the operations Intersection, Union, and Diff.
using System;
using System.Collections.Generic;
using System.Collections;

public class Set<T> {
 
  /* Invariant: At most one occurrence of an element in the array store 
     Consequtive storing from low end.
  */

  private int capacity;
  private static int DefaultCapacity = 3;
  private T[] store;
  private int next;

  public Set(int capacity){
    this.capacity = capacity;
    store = new T[capacity];
    next = 0;
  }

  public Set(): this(DefaultCapacity){
  }

  public Set(T[] elements): this(elements.Length){
    foreach(T el in elements) this.Insert(el);
  }

  // Copy constructor
  public Set(Set<T> s): this(s.capacity){
    foreach(T el in s) this.Insert(el);
  }

  public bool Member(T element){
    for(int idx = 0; idx < next; idx++)
      if (element.Equals(store[idx]))
        return true;
    return false;
  }

  public void Insert(T element){
    if (!this.Member(element)){
      if (this.Full){
        Console.WriteLine("[Resize to {0}]", capacity * 2);
        Array.Resize<T>(ref store, capacity * 2);
        capacity = capacity * 2;
      }
      store[next] = element;
      next++;
    }
  }

  public void Delete(T element){
    bool found = false;
    int  foundIdx = 0;
    for(int idx = 0; !found && (idx < next); idx++){
      if (element.Equals(store[idx])){
         found = true;
         foundIdx = idx;
      }
    }
    if (found){   // shift remaining elements left
      for(int idx = foundIdx+1; idx < next; idx++)
        store[idx-1] = store[idx];
      store[next-1] = default(T);
      next--;
    }
  }

  public int Count{
    get{
      return next;
    }
  }

  // Is this set a subset of other
  public bool Subset(Set<T> other){
    foreach(T e in this)
      if (!other.Member(e))
         return false;
    return true;
  }
     
  public Set<T> Intersection(Set<T> other){
    Set<T> res = new Set<T>(this.Count);
    foreach(T e in this)
      if (other.Member(e))
          res.Insert(e);
    return res;
  }

  public Set<T> Union(Set<T> other){
    Set<T> res = new Set<T>(this.Count + other.Count);
    foreach(T e in this) res.Insert(e);
    foreach(T e in other) res.Insert(e);
    return res;
  }

  // Subtract other elements from this set.
  public Set<T> Diff(Set<T> other){
    Set<T> res = new Set<T>(this);
    foreach(T e in other) res.Delete(e);
    return res;
  }

  public override string ToString(){
    string elRes = "";
    for(int idx = 0; idx < next; idx++) 
      if (store[idx] != null)
        elRes += " " + store[idx];
    return "{" + elRes + " "+ "}" + this.Count;
  }
  
  private class SetEnumerator: IEnumerator<T>{
 
    private readonly Set<T> set; 
    private int idx;

    public SetEnumerator (Set<T> s){
      this.set = s;
      idx = -1;   // position enumerator outside range
    }
 
    public T Current{ 
      get {
       return set.store[idx];
      }
    }

    Object IEnumerator.Current{ 
      get {
       return set.store[idx];
      }
    }

    public bool MoveNext(){
      if (idx < set.next - 1){
        idx++; 
        return true;
      }
      else
         return false;
    }

    public void Reset(){
      idx = -1;         
    }

    public void Dispose(){
    }

  }    
    
  public IEnumerator<T> GetEnumerator (){
    return new SetEnumerator(this);
  }

  private bool Full{
    get{
      return next == capacity;
    }
  }

}

Not in use - for exercise
Slide Annotated slide Contents Index
References 

Program: GCD.
#include <stdio.h>

int gcd(int i, int j){
  int small, large, remainder;

  if (i <= j)
    small = i;
  else 
    small = j;

  if (i <= j)
    large = j;
  else 
    large = i;
  
  while (small > 0){
    remainder = large % small;
    large = small;
    small = remainder;
  }
  
  return large;

}


int main(void) {
  int i, j;
 
  printf("Enter two positive integers: ");
  scanf("%d %d", &i, &j);

  printf("GCD of %d and %d is %d\n\n", i, j, gcd(i,j));
  
  return 0;
}

Not in use - fragmented program
Slide Annotated slide Contents Index
References 

Program: Demonstration of the simple type bool in C#.
  public static void BoolDemo(){
    bool b1, b2;
    b1 = true; b2 = default(bool);
    if (b1 == b2)
      Console.WriteLine("The default boolean value is true");
    else
      Console.WriteLine("The default boolean value is false");
  }   

Program: Demonstrations of the simple type char in C#.
  public static void CharDemo(){
    char ch1 = 'A',
         ch2 = '\u0041', 
         ch3 = '\u00c6', ch4 = '\u00d8', ch5 = '\u00c5',    // Æ, Ø, Å
         ch6, ch7;

    if (char.IsLetter(ch1))
       Console.WriteLine("{0} is a classificed as a letter", ch1);

    Console.WriteLine("{0} {1} {2}", ch3, ch4, ch5);
    Console.WriteLine("{0} {1} {2}", char.ToLower(ch3), 
                                     char.ToLower(ch4),
                                     char.ToLower(ch5));

    ch7 = char.Parse("B"); 
    Console.WriteLine("{0} {1}", char.GetNumericValue('3'), 
                                 char.GetNumericValue('b'));

    Console.WriteLine("{0}", CharCode('a'));
    Console.WriteLine("{0}", CharCode(ch5));
  }   

Program: Demonstrations of the simple numeric types in C#.
  public static void NumberDemo(){
    sbyte        sb1 = sbyte.MinValue;       // Signed 8 bit integer
    System.SByte sb2 = System.SByte.MaxValue;
    Console.WriteLine("sbyte: {0} : {1}", sb1, sb2);

    byte        b1 = byte.MinValue;          // Unsigned 8 bit integer
    System.Byte b2 = System.Byte.MaxValue;
    Console.WriteLine("byte: {0} : {1}", b1, b2);

    short        s1 = short.MinValue;        // Signed 16 bit integer
    System.Int16 s2 = System.Int16.MaxValue;
    Console.WriteLine("short: {0} : {1}", s1, s2);

    ushort         us1 = ushort.MinValue;    // Unsigned 16 bit integer
    System.UInt16  us2= System.Byte.MaxValue;
    Console.WriteLine("ushort: {0} : {1}", us1, us2);

    int          i1 = int.MinValue;          // Signed 32 bit integer
    System.Int32 i2 = System.Int32.MaxValue;
    Console.WriteLine("int: {0} : {1}", i1, i2);

    uint           ui1 = uint.MinValue;      // Unsigned 32 bit integer
    System.UInt32  ui2= System.UInt32.MaxValue;
    Console.WriteLine("uint: {0} : {1}", ui1, ui2);

    long         l1 = long.MinValue;         // Signed 64 bit integer
    System.Int64 l2 = System.Int64.MaxValue;
    Console.WriteLine("long: {0} : {1}", l1, l2);

    ulong           ul1 = ulong.MinValue;    // Unsigned 64 bit integer
    System.UInt64   ul2= System.UInt64.MaxValue;
    Console.WriteLine("ulong: {0} : {1}", ul1, ul2);

    float           f1 = float.MinValue;     // 32 bit floating-point
    System.Single   f2= System.Single.MaxValue;
    Console.WriteLine("float: {0} : {1}", f1, f2);

    double          d1 = double.MinValue;    // 64 bit floating-point
    System.Double   d2= System.Double.MaxValue;
    Console.WriteLine("double: {0} : {1}", d1, d2);

    decimal         dm1 = decimal.MinValue;  // 128 bit fixed-point
    System.Decimal  dm2= System.Decimal.MaxValue;
    Console.WriteLine("decimal: {0} : {1}", dm1, dm2);


    string s = sb1.ToString(),
           t = 123.ToString();

  }   

Not used - fragmented program
Slide Annotated slide Contents Index
References 

Program: A demonstrations of arrays in C#.
  public static void ArrayDemo(){
     string[]  a1;                     // a1 is uninitialized
     string[]  a2 = new string[3];     // an array with three null values

     string[]  a3 = {"a", "bb", "ccc"};     // an array with 3 strings
     string[]  a4 = new string[]{"a", "bb", "ccc"};   // equivalent
     string[]  a5 = new string[3]{"a", "bb", "ccc"};  // equivalent

//   string[]  a6 = new string[2]{"c", "b", "a"};  
//   Compile time error 
//   'Invalid rank specifier'. Not space enough in array. Omit [2]

     // a1 is assigned to a new string array.
     a1 = new string[]{"a", "bb", "ccc"};

     int[,]    b1 = new int[2,4];   
                                  // 2 rows, 4 columns
                                  // all initialized to default(int)

     int[,]    b2 = {{1,2,3,4}, {5,6,7,8}};   
     int[,]    b3 = new int[2,4]{{1,2,3,4}, {5,6,7,8}};  // equivalent

//   int[,]    b4 = new int[3,4]{{1,2,3,4}, {5,6,7,8}};  
//   Compile time error
//   'Invalid rank specifier'. Add a third row.

     // b1 is assigned to a new int arrays. 2 rows, 4 columns
     b1 = new int[,]{{1,2}, {3,4}, {5,6}, {7,8} };

     double[][] c1 = { new double[]{1.1, 2.2}, 
                       new double[]{3.3, 4.4, 5.5, 6.6} };

     Console.WriteLine("Array lengths. a1:{0} b3:{1} c1:{2}", 
                        a1.Length, b3.Length, c1.Length);
     // 3, 8, 2

     Array.Clear(a2,0,3);  // Set a[0], a[1], a[2] to default values 

     Console.WriteLine("Length of a3: {0}", a3.Length);  // 3
     Array.Resize<string>(ref a3,10);
     Console.WriteLine("Lenght of a3: {0}", a3.Length);  // 10

     Console.WriteLine("Ranks of b1 and c1: {0}, {1}", b1.Rank, c1.Rank);
     // 2, 1

     Console.WriteLine("Sorting:");
     Array.Sort(a5);
     foreach(string str in a5) Console.WriteLine(str);

  }   

Program: A demonstration of strings in C#.
  public static void StringDemo(){
     string s1        = "OOP";
     System.String s2 = "\u004f\u004f\u0050";   // equivalent
     Console.WriteLine("s1 and s2: {0} {1}", s1, s2);

     string s3 = @"OOP on
            the \n semester ""Dat1/Inf1/SW3""";
     Console.WriteLine("\n{0}", s3);

     string s4 = "OOP on \n            the \\n semester \"Dat1/Inf1/SW3\"";
     Console.WriteLine("\n{0}", s4);

     string s5 = "OOP E06".Substring(0,3);
     Console.WriteLine("The substring is: {0}", s5);

  }   

Not used
Slide Annotated slide Contents Index
References 

Program: A demonstration of if.
  public static void IfDemo(){
    int i = 0;

    /*  Illegal:  Cannot implicitly convert type 'int' to 'bool'
    if (i){
      Console.WriteLine("i is 0");
    }
    else {
      Console.WriteLine("i is not 0");
    }    
    */

    /* The type of the expression i==0 is boolean  */
    if (i == 0){
      Console.WriteLine("i is 0");
    }
    else {
      Console.WriteLine("i is not 0");
    }    
  }      

Program: A Demonstration of switch.
  public static void SwitchDemo(){
    int j = 1;

    /* Illegal: Control cannot fall through from one case label to another
    switch (j) {
      case 0:  Console.WriteLine("j is 0");
      case 1:  Console.WriteLine("j is 1");
      case 2:  Console.WriteLine("j is 2");
      default: Console.WriteLine("j is not 0, 1 or 2");
    }   
    */

    /* Break or similar jumping is needed:  */
    switch (j) {   
      case 0:  Console.WriteLine("j is 0"); break;
      case 1:  Console.WriteLine("j is 1"); break;
      case 2:  Console.WriteLine("j is 2"); break;
      default: Console.WriteLine("j is not 0, 1 or 2"); break;
    }   

    /* Falling through empty cases is possible:  */   
    switch (j) {        
      case 0: case 1:  Console.WriteLine("j is 0 or 1"); break;
      case 2: case 3:  Console.WriteLine("j is 2 or 3"); break;
      case 4: case 5:  Console.WriteLine("j is 4 or 5"); break;
      default: Console.WriteLine("j is not 1, 2, 3, 4, or 5"); break;
    }   

    /* It is possible to switch on strings:  */
    string str = "two";
    switch (str) {
      case "zero":  Console.WriteLine("str is 0"); break;
      case "one":  Console.WriteLine("str is 1"); break;
      case "two":  Console.WriteLine("str is 2"); break;
      default: Console.WriteLine("str is not 0, 1 or 2"); break;
    }   

  }      

Program: A demonstration of foreach.
  public static void ForeachDemo(){

    int[] ia = {1, 2, 3, 4, 5};
    int sum = 0;

    foreach(int i in ia)
      sum += i;

    Console.WriteLine(sum);
  }      

Program: A demonstration of try.
  public static void TryCatchDemo(){
    int i = 5, r = 0, j = 0;

    /* Windows: Compile time error. On MONO: Run time error 
    r = i / 0;
    Console.WriteLine("r is {0}", r);   
    */

    try {
      r = i / j;
      Console.WriteLine("r is {0}", r);
    } catch(DivideByZeroException e){
        Console.WriteLine("r could not be computed");
    }   
  }      

Not used
Slide Annotated slide Contents Index
References 

Program: Demonstration of simple functions in C#.
/* Right, Wrong */

using System;


/* 
public int Increment(int i){   
  return i + 1;                
}                              

public void Main (){
  int i = 5,
      j = Increment(i);
  Console.WriteLine("i and j: {0}, {1}", i, j);
} // end Main     
*/

public class FunctionDemo {

  public static void Main (){
    SimpleFunction();
  }

  public static void SimpleFunction(){   
    int i = 5,
        j = Increment(i);
    Console.WriteLine("i and j: {0}, {1}", i, j);
  }

  public static int Increment(int i){
    return i + 1;
  }    
}

Program: Demonstration of parameter passing in C#.
using System;
public class FunctionDemo {

  public static void Main (){
    ParameterPassing();
  }

  public static void ValueFunction(double d){
    d++;}

  public static void RefFunction(ref double d){
    d++;}

  public static void OutFunction(out double d){
    d = 8.0;}

  public static void ParamsFunction(out double res, 
                                    params double[] input){
    res = 0;
    foreach(double d in input) res += d;
  }

  public static void ParameterPassing(){
    double myVar1 = 5.0;
    ValueFunction(myVar1);
    Console.WriteLine("myVar1: {0:f}", myVar1);            // 5.00

    double myVar2 = 6.0;
    RefFunction(ref myVar2);
    Console.WriteLine("myVar2: {0:f}", myVar2);            // 7.00

    double myVar3; 
    OutFunction(out myVar3);
    Console.WriteLine("myVar3: {0:f}", myVar3);            // 8.00

    double myVar4;
    ParamsFunction(out myVar4, 1.1, 2.2, 3.3, 4.4, 5.5);  // 16.50
    Console.WriteLine("Sum in myVar4: {0:f}", myVar4);
  }

}

Program: Demonstration of overloaded methods in C#.
using System;

public class FunctionDemo {

  public static void Main (){
    Overloading();
  }

  public static void F(int p){
    Console.WriteLine("This is F(int) on {0}", p);
  }    

  public static void F(double p){
    Console.WriteLine("This is F(double) on {0}", p);
  }    

  public static void F(double p, bool q){
    Console.WriteLine("This is F(double,bool) on {0}, {1}", p, q);
  }    

  public static void F(ref int p){
    Console.WriteLine("This is F(ref int) on {0}", p);
  }    

  public static void Overloading(){
    int i = 7;

    F(i);             // This is F(int) on 7
    F(5.0);           // This is F(double) on 5
    F(5.0, false);    // This is F(double,bool) on 5, False
    F(ref i);         // This is F(ref int) on 7
  }

}

Not used
Slide Annotated slide Contents Index
References 

A double linked list where instances of LinkedListNode keep the list together

Button Demo GUI
Slide Annotated slide Contents Index
References 

Figure. A graphical user interface with two buttons and a textbox.

Observer Illustration
Slide Annotated slide Contents Index
References 

The subject (weather service object) to the left and its three observers (weather watcher objects) to the right. The Weather Service Object get its information various sensors.

Observer Illustration Experimental
Slide Annotated slide Contents Index
References 

The subject (Weather Service Object) and its three observers. The Weather Service Object get its information various sensors.

Set of bank account illlustration
Slide Annotated slide Contents Index
References 

A set of bank accounts and a set of check accounts

Hello World Program
Slide Annotated slide Contents Index
References 

Program: Hello World Program in C#.
using System;

class Hello{

  public static void Main(){
    Console.WriteLine("Hello World");
  }
}

Privacy Leaks - Programs for exercise
Slide Annotated slide Contents Index
References 

Program: A Mutable Date class.
public class Date{
  private ushort year;
  private byte month, day;

  public Date(ushort year, byte month, byte day){
    this.year = year; this.month = month; this.day = day;
  }

  public ushort Year{
    get{return year;}
    set{year = value;}
  }

  public byte Month{
    get{return month;}
    set{month = value;}
  }

  public byte Day{
    get{return day;}
    set{day = value;}
  }

  public override string ToString(){
    return string.Format("{0}.{1}.{2}",day, month, year);
  }
}

Program: A Person class that can return its private birth Date.
public class Person{

  private string name;
  private Date dateOfBirth, dateOfDeath;

  public Person (string name, Date dateOfBirth){
    this.name = name;
    this.dateOfBirth = dateOfBirth;
    this.dateOfDeath = null;
  }

  public string Name{
    get {return name;}
    set {name = value;}
  }

  public Date DateOfBirth{
    get {return dateOfBirth;}
  }

  public ushort AgeAsOf(Date d){
    return (ushort)(d.Year - dateOfBirth.Year);
  }

  public bool Alive(){
    return dateOfDeath == null;
  }

  public override string ToString(){
    return "Person: " + name + " " + dateOfBirth;
  }

}

Program: A client of the Person which modifies the returned birth Date.
using System;

class Client{

  public static void Main(){

    Person p = new Person("Hanne", new Date(1926, 12, 24));

    Date d = p.DateOfBirth;
    d.Year -= 100;
    Console.WriteLine("{0}", p);

    Date today = new Date(2006,8,31);
    Console.WriteLine("Age of Hanne as of {0}: {1}.", 
                      today, p.AgeAsOf(today));
  }

}

Program: The output of the Person client program.
Person: Hanne 24.12.1826
Age of Hanne as of 31.8.2006: 180.

Polygon Stuff
Slide Annotated slide Contents Index
References 

Program: A sample implementation of class Polygon.
using System;

public class Polygon {

  private Point[] corners;
  
  public Polygon(params Point[] corners){
    this.corners = new Point[corners.Length];

    // Copy corners into instance variable:
    for(int i = 0; i < corners.Length; i++)
      this.corners[i] = new Point(corners[i]);
  }

  private Line[] Edges(){
    Line[] res = new Line[corners.Length];
    int Lgt = corners.Length;
    for (int i = 0; i < Lgt - 1; i++)
       res[i] = new Line(corners[i], corners[i+1]);
    res[Lgt-1] = new Line(corners[Lgt-1], corners[0]);
    return res;
  }

  public virtual double Circumference(){
    double res = 0;
    foreach(Line ln in this.Edges())
      res += ln.Length();
    return res; 
  }

  public virtual int Rank{
    get {
      return corners.Length;}
  }

}

internal class Line{

 private Point p1, p2;
 
 public Line(Point p1, Point p2){
   this.p1 = new Point(p1);
   this.p2 = new Point(p2);
 }

 public double Length(){
   return Math.Sqrt(
            Square(p1.X - p2.X) + 
            Square(p1.Y - p2.Y));
 }

 private static double Square(double a){
   return a * a;
 }
}    

Program: Class Point with MidPoint and RotateAroundPoint.
// A versatile version with Rotation and internal methods
// for rectangular and polar coordinates. 

using System;

public class Point {

  private double r, a;            //  Data repr: radius, angle

  private Point(double r, double a){
     this.r = r; this.a = a;
  }

  // Copy constructor.
  public Point(Point p){
     this.r = p.r;
     this.a = p.a;
  }

  public static Point MakePolarPoint(double r, double a){
    return new Point(r, a);
  }

  public static Point MakeRectangularPoint(double x, double y){
    return new Point(RadiusGivenXy(x,y), AngleGivenXy(x,y));
  }

  public double X {
    get {return XGivenRadiusAngle(r,a);}
  }

  public double Y {
    get {return YGivenRadiusAngle(r,a);}
  }

  public double Radius {
    get {return r;}
  }

  public double Angle{
    get {return a;}
  }

  // The midpoint between p and this point
  public Point MidPoint(Point p){
    return MakeRectangularPoint(this.X + (p.X - this.X)/2,
                                this.Y + (p.Y - this.Y)/2);
  }

  // Return a new point which corresponds to this point 
  // rotated angle around p
  public Point RotateAroundPoint(Point p, double angle){
    Point pointToRotate = MakeRectangularPoint(this.X, this.Y);
    pointToRotate.Move(-p.X, -p.Y);
    pointToRotate.Rotate(angle);
    pointToRotate.Move(p.X, p.Y);
    return pointToRotate;
  }

  public void Move(double dx, double dy){
    double x, y;
    x = XGivenRadiusAngle(r,a);   y = YGivenRadiusAngle(r,a); 
    r = RadiusGivenXy(x+dx, y+dy);
    a = AngleGivenXy(x+dx, y+dy);
  }

  public void Rotate(double angle){
    a += angle;
  }

  public override string ToString(){
    return  "(" + XGivenRadiusAngle(r,a) + "," + YGivenRadiusAngle(r,a) + ")";
  }

  private static double RadiusGivenXy(double x, double y){
    return Math.Sqrt(x * x + y * y);
  }

  private static double AngleGivenXy(double x, double y){
    return Math.Atan2(y,x);
  }

  private static double XGivenRadiusAngle(double r, double a){
    return r * Math.Cos(a);
  }

  private static double YGivenRadiusAngle(double r, double a){
    return r * Math.Sin(a);
  }

  
}

Bank Account classes
Slide Annotated slide Contents Index
References 

Program: All bank account classes - for exercise.
using System;

public class BankAccount {

   protected double interestRate;
   protected string owner;
   protected decimal balance;

   public BankAccount(string o, decimal b, double ir) {
      this.interestRate = ir;
      this.owner = o; 
      this.balance = b;
   }

   public BankAccount(string o, double ir):
     this(o, 0.0M, ir) {
   }

   public virtual decimal Balance {
     get {return balance;}
   }

   public virtual void Withdraw (decimal amount) {
      balance -= amount;
   }

   public virtual void Deposit (decimal amount) {
      balance += amount;
   }

   public virtual void AddInterests() {
      balance += balance * (Decimal)interestRate;
   }    

   public override string ToString() {
      return owner + "'s account holds " +
            + balance + " kroner";
   }
} 


public class CheckAccount: BankAccount {

   // Instance variables are inherited

   public CheckAccount(string o, double ir): 
     base(o, 0.0M, ir) {
   }

   public CheckAccount(string o, decimal b, double ir): 
     base(o, b, ir) {
   }

   // Method Balance is inherited
   // Method Deposit is inherited
   // Method AddInterests is inherited

   public override void Withdraw (decimal amount) {
      base.Withdraw(amount);
      if (amount < balance)
         interestRate = -0.10;
   }

   public override string ToString() {
      return owner + "'s check account holds " +
            + balance + " kroner";
   }
} 

public class SavingsAccount: BankAccount {

   // Instance variables are inherited

   public SavingsAccount(string o, double ir): 
     base(o, 0.0M, ir) {
   }

   public SavingsAccount(string o, decimal b, double ir): 
     base(o, b, ir) {
   }

   // Method Balance is inherited
   // Method Deposit is inherited

   public override void Withdraw (decimal amount) {
      if (amount < balance)
          base.Withdraw(amount);
      else
          throw new Exception("Cannot withdraw");
   }

   public override void AddInterests() {
      balance = balance + balance * (decimal)interestRate 
                        - 100.0M;
   }    

   public override string ToString() {
      return owner + "'s check account holds " +
            + balance + " kroner";
   }
} 

public class LotteryAccount: BankAccount {

   // Instance variables are inherited

   protected static Lottery lottery  = Lottery.Instance(3);

   public LotteryAccount(string o, decimal b): 
     base(o, b, 0.0) {
   }

   // Method Balance is inherited
   // Method Deposit is inherited
   // Method Withdraw is inherited

   public override void AddInterests() {
      int luckyNumber = lottery.DrawLotteryNumber;
      balance = balance + lottery.AmountWon(luckyNumber);
   }    

   public override string ToString() {
      return owner + "'s lottery account holds " +
            + balance + " kroner";
   }
} 

public class Lottery{

  private static Random rdm = new Random(unchecked((int)DateTime.Now.Ticks));

  private int difficulty;
  private readonly int winningNumber;
  private readonly decimal amountWon;
  private static Lottery uniqueInstance = null;

  private Lottery(int difficulty){
    this.difficulty = difficulty;
    this.winningNumber = rdm.Next(difficulty);
    this.amountWon = 500000.00M;
  }

  public static Lottery Instance(int difficulty){
    if (uniqueInstance == null)
      uniqueInstance = new Lottery(difficulty);
    return uniqueInstance;
  }

  public int DrawLotteryNumber{
    get {return rdm.Next(difficulty);}
  }

  public bool IsWinningNumber(int number){
    return number == winningNumber;
  }

  public decimal AmountWon(int luckyNumber){
    decimal res;
    if (IsWinningNumber(luckyNumber))
       res = amountWon;
    else
       res = 0.0M;
    return res;
  }
}

public class AccountClient{

  public static void Main(){
     BankAccount[] accounts = 
      new BankAccount[5]{
        new CheckAccount("Per",1000.0M, 0.03),
        new SavingsAccount("Poul",1000.0M, 0.07),
        new CheckAccount("Kurt",10.0M, 0.02),
        new LotteryAccount("Bent",10500.0M),
        new LotteryAccount("Lone",11500.0M)
      };

    foreach(BankAccount ba in accounts){
       ba.Deposit(1000.0M);  
    }  
 
    accounts[2].Withdraw(1050.0M);  // Kurt's

    foreach(BankAccount ba in accounts){
      ba.AddInterests();  
    }  

    foreach(BankAccount ba in accounts){
      Console.WriteLine("{0}", ba);
    }
  }

}  

Stack - preparation to exceptions
Slide Annotated slide Contents Index
References 

Program: A solution to the exercise.
using System;

public class StackWithArray: Stack{ 

  private Object[] elements;
  private int nextPush;
  private int MaxSize; 

  public StackWithArray(int MaxSize){
    elements = new Object[MaxSize];
    nextPush = 0;
    this.MaxSize = MaxSize;
  }
  
   public override void Push(Object el){
     if (!Full){
       elements[nextPush] = el;
       nextPush++;
    }
  }

   public override void Pop(){
   if (!Empty)
     nextPush--;
   }

   public override Object Top{
    get{
      if (!Empty)
         return elements[nextPush-1];
      else return "not possible";}
   }

   public override bool Full{
    get{return nextPush >= MaxSize;}
   }

   public override bool Empty{
    get{return nextPush == 0;}
   }

   public override int Size{
    get{return nextPush;}
   }   

  public override String ToString(){
    string res = "Stack: ";
    for(int i = 0; i < nextPush; i++){
      res += elements[i] + " ";}
    return res;
  }

}

Program: A sample client program of class Stack.
using System;

class C{

  public static void Main(){

    Stack s = new StackWithArray(10);

    Console.WriteLine("Empty: {0}", s.Empty);
    Console.WriteLine("Full: {0}", s.Full);

    s.Push(5); s.Push(6);  s.Push(7);      
    s.Push(15); s.Push(16);  s.Push(17); 
    s.Push(18); s.Push(19);  s.Push(20); 
    s.Push(21); 

    Console.WriteLine("{0}", s.Size);
    Console.WriteLine("{0}", s.Top);
    Console.WriteLine("{0}", s);

    s.Pop();s.Pop();s.Pop();s.Pop();s.Pop();s.Pop();s.Pop();

    Console.WriteLine("Empty: {0}", s.Empty);
    Console.WriteLine("Full: {0}", s.Full);
    Console.WriteLine("Top: {0}", s.Top);

    Console.WriteLine("{0}", s);
    s.ToggleTop();
    Console.WriteLine("{0}", s);

  }

}

Triangle illustration
Slide Annotated slide Contents Index
References 

Figure. The hierarchy of triangle classes. The root class represents the most general triangle. The son to the left represents an isosceles triangle (where two sides are equal lengths). The son to the right represents a right triangle, where one of the angles is 90 degrees. The triangle at the bottom left is an equilateral trianlge (where all three sides are of equal lengths). The triangle at the bottom right is both an isosceles triangle and a right triangle.

Musical Element Composite
Slide Annotated slide Contents Index
References 

An extract of the Windows Form classes for GUI building. We see two Composites among these classes.

For exercise purposes
Slide Annotated slide Contents Index
References 

Program: A BankAccount class with a funny Balance property.
using System;

public class BankAccount {

   private string owner;
   private decimal balance;

   public BankAccount(string owner, decimal balance) {
      this.owner = owner; 
      this.balance = balance;
   }

   public decimal Balance {
     get {return balance * 2;} 
     set {balance = value - 50;}
   }   

   public override string ToString() {
      return owner + "'s account holds " +
            + balance + " kroner";
   }
} 

Program: A client of the funny BankAccount.
using System;

class C{

  public static void Main(){
    BankAccount ba = new BankAccount("Peter", 1000);
    Console.WriteLine(ba);

    Console.WriteLine("Balance = {0}", ba.Balance);
    Console.WriteLine(ba);

    ba.Balance += 100;
    Console.WriteLine(ba);
  }

}

For exercise purposes in lecture about classes
Slide Annotated slide Contents Index
References 

Program: A version of class Point modified to use polar coordinates - For exercise.
// A very simple class point with public data representation.
// An incomplete sketch.
// This version uses polar representation.
// NOT RECOMMENDED because of public data representation.

using System;

public class Point {
  public double radius, angle;

  public Point(double x, double y){
    radius = ...
    angle = ...
  }

  public void Move(double dx, double dy){
    radius = ...
    angle = ...
  }

  public void Rotate(double angle){
    this.angle += angle;
  }

  public override string ToString(){
    ...
  }



  private static double RadiusGivenXy(double x, double y){
    return Math.Sqrt(x * x + y * y);
  }

  private static double AngleGivenXy(double x, double y){
    return Math.Atan2(y,x);
  }

  private static double XGivenRadiusAngle(double r, double a){
    return r * Math.Cos(a);
  }

  private static double YGivenRadiusAngle(double r, double a){
    return r * Math.Sin(a);
  }


}

For exercise
Slide Annotated slide Contents Index
References 

Program: BankAccount Skeleton - For exercise.
using System;

public class BankAccount {

   private string owner;
   private decimal balance;
   private BankAccount leftAccount, rightAccount;

   public BankAccount(string owner, decimal balance) {
      this.owner = owner; 
      this.balance = balance;
      this.leftAccount = null;
      this.rightAccount = null;
   }

   public BankAccount(string owner, decimal balance, BankAccount leftAccount, BankAccount rightAccount) {
      this.owner = owner; 
      this.balance = balance;
      this.leftAccount = leftAccount;
      this.rightAccount = rightAccount;
   }

   private bool LeafAccount(){
      return leftAccount == null && rightAccount == null;
   }
 
   public decimal Balance () {
     // Exercise
   }

   public void Withdraw (decimal amount) {
     // Exercise
   }

   public void Deposit (decimal amount) {
     // Exercise
   }

   public void DistributeEven(){
     // Exercise
   }

   public override string ToString() {
      return String.Format("{0} {1,12:c2} (local amount: {2,12:c2})", owner, Balance(), balance);
  }

} 

Program: BankAccount Client - For exercise.
using System;

class Client{

  BankAccount ba1, ba2, ba3, ba4, ba5, ba6, ba7;

  public static void Main(){
   (new Client()).Go();
  }

  public Client(){
   ba1 = new BankAccount("Per", 100);
   ba2 = new BankAccount("Poul", 200);
   ba3 = new BankAccount("Pia", 300);
   ba4 = new BankAccount("Mette", 400);
   ba5 = new BankAccount("Rasmus", 500, ba1, ba2);
   ba6 = new BankAccount("Lotte", 600, ba3, ba4);
   ba7 = new BankAccount("Kurt", 700, ba5, ba6);

   // The constructions above derive this pyramid tree structure:
   //   ba7
   //     ba5
   //       ba1
   //       ba2
   //     ba6
   //       ba3
   //       ba4
  }     

  public void Go(){
   WriteAccounts("Initial situation");

   ba7.Deposit(1000);
   WriteAccounts("After depositing 1000 kr.");

   ba7.Withdraw(1000);
   WriteAccounts("After withdrawing 1000 kr.");

   ba7.DistributeEven();
   WriteAccounts("After distributing even");
  }

  public void WriteAccounts(string situation){
   Console.WriteLine(situation);
   Console.WriteLine(ba1);
   Console.WriteLine(ba2);
   Console.WriteLine(ba3);
   Console.WriteLine(ba4);
   Console.WriteLine(ba5);
   Console.WriteLine(ba6);
   Console.WriteLine(ba7); 
   Console.WriteLine();
  }

}

For exercise
Slide Annotated slide Contents Index
References 

Program: Interval Overlapping - For exercise.
using System;
using System.Collections;

public struct Interval{

  private readonly int from, to;  
  private bool empty;

  public Interval(int from, int to){   
    this.from = from;
    this.to = to;
    this.empty = false;
  }

  /* Constructs an empty interval. A Factory method. */
  public static Interval MakeEmptyInterval (){
    Interval res = new Interval(); 
    res.empty = true;
    return res;
  }

  public int From{   
    get {return from;}
  }

  public int To{
    get {return to;}
  }

  public bool Empty{
    get {return empty;}
  }

  public int Length{  
    get {return Math.Abs(to - from) + 1;}                
  }

  public int this[int i]{
    get {if (from <= to){
           if (i >= 0 && i <= Math.Abs(from-to))
               return from + i;
           else throw new Exception("Index out of interval bounds"); }
         else if (from > to){
           if (i >= 0 && i <= Math.Abs(from-to))
               return from - i;
           else throw new Exception("Index out of interval bounds"); }
         else throw new Exception("Should not happen"); }
  }

  public static Interval operator +(Interval i, int j){  
    return new Interval(i.From + j, i.To + j);
  }

  public static Interval operator +(int j, Interval i){  
    return new Interval(i.From + j, i.To + j);
  }

  public static Interval operator >>(Interval i, int j){ 
    return new Interval(i.From, i.To + j);
  }

  public static Interval operator <<(Interval i, int j){ 
    return new Interval(i.From + j, i.To);
  }

  public static Interval operator *(Interval i, int j){  
    return new Interval(i.From * j, i.To * j);
  }

  public static Interval operator *(int j, Interval i){  
    return new Interval(i.From * j, i.To * j);
  }

  public static Interval operator -(Interval i, int j){  
    return new Interval(i.From - j, i.To - j);
  }

  public static Interval operator !(Interval i){   
    return new Interval(i.To, i.From);
  }    

  private class IntervalEnumerator: IEnumerator{    
                                                    
    private readonly Interval interval;             
    private int idx;

    public IntervalEnumerator (Interval i){
      this.interval = i;
      idx = -1;   // position enumerator outside range
    }
 
    public Object Current{ 
         get {return (interval.From < interval.To) ? 
                       interval.From + idx :
                       interval.From - idx;}
    }

    public bool MoveNext (){
      if ( idx < Math.Abs(interval.To - interval.From))
         {idx++; return true;}
      else
         {return false;}
    }

    public void Reset(){
      idx = -1;         
    }
  }    
    
  public IEnumerator GetEnumerator (){     
    return new IntervalEnumerator(this);   
  }

}

Program: Interval Overlapping Client- For exercise.
using System;

public class app {

  public static void Main(){

    Interval iv1 = new Interval(16, 4),
             iv2 = new Interval(10,38),
             iv3 = iv1 & iv2;

    if (iv3.Empty)
      Console.WriteLine("iv3 is empty");
    else
      Console.WriteLine("iv3 is NOT empty");

    Console.WriteLine("{0}, {1}, {2}, {3}", iv3.From,  iv3.To,  iv3.Length, iv3.Empty);  

    foreach(int k in iv3){
      Console.Write("{0,4}", k);
    }
    Console.WriteLine();

  }

}

 

Chapter 0: Extra Stuff
Course home     Author home     About producing this web     Previous lecture (top)     Next lecture (top)     Previous lecture (bund)     Next lecture (bund)     
Generated: May 3, 2010, 14:53:30