Hi. Welcome to Lab Eight. 

Today's lab assignment: 

  follow along and understand

  type and ask questions if you don't 

  submit what you have at the end of the class period

What is a Horse? 

class Horse {
  void talk() {
    System.out.println("Howdy."); 
  }
}

Horse = { talk() }

Unicorn = Horse U { sing() }

class Unicorn extends Horse {
  void sing() {
    System.out.println("My horn can pierce the sky"); 
  } 
}

So we started from this and we ended up with this first solution:

class Horse {
  void talk() {
    System.out.println("Howdy."); 
  }
}

class Unicorn extends Horse {
  void sing() {
    System.out.println("My horn can pierce the sky");
  }
}

class Example {
  public static void main(String[] args) {
     Horse a = new Horse(); 
     System.out.println( a ); 
     a.talk(); 
     Unicorn b = new Unicorn(); 
     System.out.println( b ); 
     b.sing(); // piercing the sky 
     b.talk(); // also works, by inheritance 
     Horse c = new Unicorn(); // polymorphism 
     // c is like a remote control with one button: talk()
     System.out.println( c ); // prints Unicorn@5f326c
     // c.sing(); // doesn't work 
     ((Unicorn) c).sing(); // casting 
     Horse[] horses = new Horse[3]; 
     horses[0] = new Horse(); 
     horses[1] = new Unicorn(); 
     horses[2] = new Unicorn(); 
     System.out.println( java.util.Arrays.toString( horses ) );    
     for (int i = 0; i < horses.length; i = i + 1) {
       horses[i].talk();  
     }
  }
}

So that's one aspect. 

Now I am going to make changes:

Horse = { talk() }

Unicorn = Horse U { sing(), talk() }

class Horse {
  void talk() {
    System.out.println("Howdy."); 
  }
}

class Unicorn extends Horse {
  void sing() {
    System.out.println("My horn can pierce the sky");
  }
  void talk() {
    System.out.println("Bonjour."); 
    super.talk(); 
  }
}

class Example {
  public static void main(String[] args) {
    Horse a;
    a = new Horse(); 
    a.talk(); 
    Horse b = new Unicorn(); 
    b.talk(); // prints Bonjour
  }
}

This is an example of dynamic method lookup. 

How does this work for Circles and Rectangles? 

class Point {
  double x; // on the horizontal increasing from left to right 
  double y; // on the vertical increasing as you go down 
  Point(double x, double y) {
    this.x = x;
    this.y = y; 
  }
  double distanceTo(Point other) {
    double dx = this.x - other.x;
    double dy = this.y - other.y;
    return Math.sqrt( dx * dx + dy * dy ); 
  }
}

class Shape {
  
}

class Circle extends Shape {
  double radius;
  Point center; 
  Circle(double radius, Point center) {
    this.radius = radius;
    this.center = center;
  }
  double area() {
    return Math.PI * this.radius * this.radius;  
  }
}

class Rectangle extends Shape {
  double width;
  double height;
  Point center; 
  Rectangle(double width, double height, Point center) {
    this.width = width;
    this.height = height;
    this.center = center;
  }
  double area() {
    return this.width * this.height;  
  }
}

class Example {
  public static void main(String[] ags) {
    Shape[] shapes = new Shape[3]; 
    shapes[0] = new Circle(3, new Point(4, 5)); 
    shapes[1] = new Rectangle(2, 5, new Point(1, -5)); 
    shapes[2] = new Rectangle(7, 3, new Point(-5, 25)); 
    System.out.println( java.util.Arrays.toString( shapes ) ); 
  }
}