Exercises in this lecture   Go to the notes, in which this exercise belongs -- Keyboard shortcut: 'u'   Alphabetic index   Course home   

Exercise solution:
Exceptions in class Stack


We introduce a StackUnderflowException and a StackOverflowException together with the abstract class. Notice that the method ToggleTop throws the StackUnderflowException if the stack has less than two elements.

using System;

public abstract class Stack{ 
  
  abstract public void Push(Object el);

  abstract public void Pop();

  abstract public Object Top{
    get;}

  abstract public bool Full{
    get;}

  abstract public bool Empty{
    get;}

  abstract public int Size{
    get;}   

  public void ToggleTop(){
    if (Size >= 2){
      Object topEl1 = Top;  Pop();
      Object topEl2 = Top;  Pop();
      Push(topEl1); Push(topEl2);
    }
    else throw new StackUnderflowException();
  }   

  public override String ToString(){
    return("Stack");
  }
}

public class StackOverflowException: ApplicationException{
}

public class StackUnderflowException: ApplicationException{
}

Here follows the refined non-abstract specialization of class Stack, which includes exception handling:

using System;

public class AStack: Stack{ 

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

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

   public override void Pop(){
     if (!Empty)
       nextPush--;
     else throw new StackUnderflowException();
   }

   public override Object Top{
    get{
      if (!Empty)
        return elements[nextPush-1];
      else throw new StackUnderflowException();
    }
   }

   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;
  }

}

The following client triggers the requested exception handling:

using System;

class C{

  public static void Main(){

    Stack s = new AStack(10);

    try{
      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(15); s.Push(16);  s.Push(17); 
      s.Push(15); 
  
      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();s.Pop(); s.Pop(); s.Pop();
  
      Console.WriteLine("Empty: {0}", s.Empty);
      Console.WriteLine("Full: {0}", s.Full);
  
      Console.WriteLine("{0}", s);
      s.ToggleTop();
      Console.WriteLine("{0}", s);
   }
   catch (StackOverflowException){
     Console.WriteLine("StackOverflow");
   }
   catch (StackUnderflowException){
     Console.WriteLine("StackUnderflow");
   }

  }

}

Notice, in this client class, that the first encountered stack error causes termination of Main. There is no notion of 'returning back to' or 'retrying' the offending stack operation. This may not always be satisfactory.