CS 1723, Extending Classes:
Different Kinds of Progressions

The following example gives a base class named Progression that has some of the parts common to a variety of progressions. This class is extended by three classes giving specific kinds of progressions:

Then there are two classes with main functions that show how to create and print these progressions in two different ways: TestProgression and TestProgression2.

Many features of extending classes (also called inheritance) are illustrated in this example, which we will cover in class.

// Progression: various kinds of progressions
public class Progression { 
   protected double first; // first value of progression
   protected double curr; // current value of progression, initially first
   protected int n; // number of items to print

   // Progression: constructors
   public Progression() {  
      first = curr = 1; n = 12;
   }

   // Progression: constructors
   public Progression(double first) {  
      this.first = first;
      n = 12;
   }

   // firstValue: return the first value
   protected double firstValue() {
      curr = first;
      return curr;
   }

   // nextValue: return next value
   protected double nextValue() {
      return ++curr;
   }

   // printProgression: print data for debugging
   public void printProgression() {
      System.out.print(getName() + ": ");
      printWithoutDot(firstValue());
      for (int i = 0; i < n; i++) {
         System.out.print(" "); 
         printWithoutDot(nextValue());
      }
      System.out.println();
   }

   // printWithoutDot: print double, but without dot if an int
   public void printWithoutDot(double x) {
      if ((int)x == x) System.out.print((int)x);
      else System.out.print(x);
   }

   // getName: return the name of the class
   public String getName() {
      return "General";
   }

   public static void main(String[] args) {
      Progression p1 = new Progression();
      p1.printProgression();
      Progression p2 = new Progression(7.5);
      p2.printProgression();
   }
}

// ArithProgression: arithmetic progressions public class ArithProgression extends Progression { protected double incr; // increment for arithmetic progression // ArithProgression: constructors public ArithProgression () { super(); incr = 1; } public ArithProgression (double first, double incr) { super(first); this.incr = incr; } // nextValue: return next value protected double nextValue() { curr += incr; return curr; } // getName: return the name of the class public String getName() { return "Arithmetic"; } }
// GeomProgression: geometric progressions public class GeomProgression extends Progression { protected double incr; // increment for geometric progression // GeomProgression: constructors public GeomProgression () { super(); incr = 2; } public GeomProgression (double first, double incr) { super(first); this.incr = incr; } // nextValue: return next value protected double nextValue() { curr *= incr; return curr; } // getName: return the name of the class public String getName() { return "Geometric"; } }
// FibonProgression: Fibonacci progressions public class FibonProgression extends Progression { protected double second; // second value for Fibonacci progression private boolean firstTime; // the first time nextValue is called // FibonProgression: constructors public FibonProgression () { super(); second = 1; firstTime = true; } public FibonProgression (double first, double second) { super(first); this.second = second; firstTime = true; } // nextValue: return next value protected double nextValue() { if (firstTime) { firstTime = false; return second; } curr = first + second; first = second; second = curr; return curr; } // getName: return the name of the class public String getName() { return "Fibonacci"; } }
// TestProgression: test various progressions public class TestProgression { public static void main(String[] args) { Progression p1 = new Progression(); p1.printProgression(); Progression p2 = new Progression(7.5); p2.printProgression(); Progression a0 = new ArithProgression(); a0.printProgression(); Progression a1 = new ArithProgression(2, 3); a1.printProgression(); Progression a2 = new ArithProgression(3, 0.25); a2.printProgression(); Progression g0 = new GeomProgression(); g0.printProgression(); Progression g1 = new GeomProgression(2, 3); g1.printProgression(); Progression g2 = new GeomProgression(3, 0.5); g2.printProgression(); Progression f0 = new FibonProgression(); f0.printProgression(); Progression f1 = new FibonProgression(1, 3); f1.printProgression(); Progression f2 = new FibonProgression(1, 1.5); f2.printProgression(); } }
// TestProgression2: test various progressions public class TestProgression2 { public static void main(String[] args) { Progression[] p = new Progression[11]; p[0] = new Progression(); p[1] = new Progression(7.5); p[2] = new ArithProgression(); p[3] = new ArithProgression(2, 3); p[4] = new ArithProgression(3, 0.25); p[5] = new GeomProgression(); p[6] = new GeomProgression(2, 3); p[7] = new GeomProgression(3, 0.5); p[8] = new FibonProgression(); p[9] = new FibonProgression(1, 3); p[10] = new FibonProgression(1, 1.5); for (int i = 0; i < p.length; i++) p[i].printProgression(); } }
Here is a sample run (user input in bold) of both TestProgression and TestProgression2 (the outputs are exactly the same):
% javac TestProgression2.java
% java TestProgression2
General: 1 2 3 4 5 6 7 8 9 10 11 12 13
General: 7.5 8.5 9.5 10.5 11.5 12.5 13.5 14.5 15.5 16.5 17.5 18.5 19.5
Arithmetic: 1 2 3 4 5 6 7 8 9 10 11 12 13
Arithmetic: 2 5 8 11 14 17 20 23 26 29 32 35 38
Arithmetic: 3 3.25 3.5 3.75 4 4.25 4.5 4.75 5 5.25 5.5 5.75 6
Geometric: 1 2 4 8 16 32 64 128 256 512 1024 2048 4096
Geometric: 2 6 18 54 162 486 1458 4374 13122 39366 118098 354294 1062882
Geometric: 3 1.5 0.75 0.375 0.1875 0.09375 0.046875 0.0234375 0.01171875 0.005859375 0.0029296875 0.00146484375 7.32421875E-4
Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144 233
Fibonacci: 1 3 4 7 11 18 29 47 76 123 199 322 521
Fibonacci: 1 1.5 2.5 4 6.5 10.5 17 27.5 44.5 72 116.5 188.5 305