Howdy.

Dustin was asking about arrows. 

Perhaps I will pursue this more over the weekend. 

The idea would be to encapsulate the math in an object somewhere.

Until then I gave you a link to a program that more directly shows arrows.

http://silo.cs.indiana.edu:8346/h212/spr2020/0303/BevelArrows.java.phps

This week you have midterm interviews. 

--

Today: abstract clases, interfaces, constructor chaining. 

Java programs are made out of class. 

Classes are containers. They contain members: variables and methods. 

Members could be static and non-static. If a member is non-static it belongs to the blueprint. 

There is one blueprint for each class. It's allows us to make objects. 

class Circle {
  


class Rectangle {
  
}

They both extend Object. 

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Circle a = new Circle()
> Rectangle b = new Rectangle()
> Object c = new Circle()
> a
Circle@672d02d4
> b
Rectangle@1bf4c580
> c
Circle@3122e597


I am showing: 

(a) the default no-arg constructor 

(b) the class extension mechanism (e.g. a Circle is an Object and inherits from it etc.) 

(c) polymorphism is a consequence of the class extension mechanism 

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Circle a = new Circle()
> Rectangle b = new Rectangle()
> Object c = new Circle()
> a
Circle@672d02d4
> b
Rectangle@1bf4c580
> c
Circle@3122e597


https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html

https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#toString()

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Circle c = new Circle()
> c
Circle@4d06a0d6
> c.toString()
"Circle@4d06a0d6"


Every Circle inherits from Object (e.g., toString()).

https://docs.oracle.com/javase/10/docs/api/javax/swing/JFrame.html

class Circle extends Object {
  


Here's a phenomenon that we have not seen yet today: overriding or dynamic method lookup. 

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Circle c = new Circle()
> c
Circle@4d06a0d6
> c.toString()
"Circle@4d06a0d6"


But I change it to over-ride the method:

class Circle extends Object {
  public String toString() {
    return "I am a Circle"; 
  }


Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Circle c = new Circle()
> c
I am a Circle
> c.toString()
"I am a Circle"


--

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Object[] u = new Object[3]
> u
{ null, null, null }
> u[0] = new Circle()
I am a Circle
> u[1] = new Rectangle()
Rectangle@3c0f38ea
> u[2] = "OK"
"OK"
> u
{ I am a Circle, Rectangle@3c0f38ea, OK }


--

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Circle a = new Circle()
> a.area()
3.141592
> Rectangle b = new Rectangle()
> b.area()
2.71828
> import java.util.ArrayList
> ArrayList<Object> c
> c
null
> c = new ArrayList<Object>()
[]
> c
[]
> c.add(new Circle())
true
> c.add(new Rectangle())
true
> c
[I am a Circle, Rectangle@615c8db]
> c.get(0)
I am a Circle
> c.get(0).area()
Static Error: No method in Object has name 'area'
> ((Circle)c.get(0)).area()
3.141592


--

class Shape {
   
}

class Circle extends Shape {
  public String toString() {
    return "I am a Circle"; 
  }
  public double area() {
    return 3.141592;  
  }


class Rectangle extends Shape {
  public double area() {
    return 2.71828;  
  }
}

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Shape[] a = new Shape[3]
> a[0] = new Circle()
I am a Circle
> a[0].area()
Static Error: No method in Shape has name 'area'
> ((Circle)a[0]).area()
3.141592


--

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Shape[] a = new Shape[2]; 
> a
{ null, null }
> a[0] = new Circle(2);
> a[0]
I am a Circle
> a[0].area()
12.566370614359172


--

class Shape {
  public double area() {
    return -1;  
  }
}

--

class Rectangle extends Shape {
  private int width, height; 
  public Rectangle(int w, int h) {
    this.width = w; 
    this.height = h; 
  }
  public double area() {
    return this.width * this.height;  
  }
}

--

class Circle extends Shape {
  private int radius; 
  public Circle(int r) {
    this.radius = r; 
  }
  public String toString() {
    return "I am a Circle"; 
  }
  public double area() {
    return Math.PI * Math.pow(this.radius, 2);
  }


--

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Shape a = new Shape()
> a
Shape@60aa4419
> a.area()
-1.0


--

abstract class Shape {
  public double area() {
    return -1;  
  }
}

--

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> Shape a = new Shape()
Static Error: Cannot construct a Shape: a concrete class is required
> Shape a = new Circle()
Static Error: No constructor in Circle matches this invocation
    Arguments: ()
    Expected return type: Shape
    Candidate signatures: Circle(int)
> Shape a = new Circle(3)
> a
I am a Circle
> a.area()
28.274333882308138


--

abstract class Shape {
  public abstract double area();
}

--

interface Shape {
  public double area();
}

--

class Rectangle implements Shape {
  private int width, height; 
  public Rectangle(int w, int h) {
    this.width = w; 
    this.height = h; 
  }
  public double area() {
    return this.width * this.height;  
  }
}

--

class Circle implements Shape {
  private int radius; 
  public Circle(int r) {
    this.radius = r; 
  }
  public String toString() {
    return "I am a Circle"; 
  }
  public double area() {
    return Math.PI * Math.pow(this.radius, 2);
  }


--

public class Example {
  public static void main(String[] args) {
    Shape[] shapes = new Shape[5]; 
    shapes[0] = new Circle(1); 
    shapes[1] = new Circle(2); 
    shapes[2] = new Rectangle(6, 4); 
    shapes[3] = new Circle(3); 
    shapes[4] = new Rectangle(6, 6); 
    for (Shape shape : shapes)
      System.out.println( shape.area() ); 
  }
}

--

Final code: 

abstract class Shape implements Comparable<Shape> {
  public abstract double area();
  public int compareTo(Shape other) {
     if (this.area() > other.area())
       return -1; // I come first 
     else if (this.area() < other.area()) 
       return 1; // other comes first 
     else 
       return 0; 
  }
}

--

class Circle extends Shape {
  private int radius; 
  public Circle(int r) {
    this.radius = r; 
  }
  public String toString() {
    return "I am a Circle"; 
  }
  public double area() {
    return Math.PI * Math.pow(this.radius, 2);
  }


--

class Rectangle extends Shape {
  private int width, height; 
  public Rectangle(int w, int h) {
    this.width = w; 
    this.height = h; 
  }
  public double area() {
    return this.width * this.height;  
  }
}

--

import java.util.Arrays; 

public class Example {
  public static void main(String[] args) {
    Shape[] shapes = new Shape[5]; 
    shapes[0] = new Circle(1); 
    shapes[1] = new Circle(2); 
    shapes[2] = new Rectangle(6, 4); 
    shapes[3] = new Circle(3); 
    shapes[4] = new Rectangle(6, 6); 
    for (Shape shape : shapes)
      System.out.print( " " + shape.area() ); 
    System.out.println(); // initial order
    Arrays.sort( shapes ); // sorting should happen here 
    for (Shape shape : shapes)
      System.out.print( " " + shape.area() ); 
    System.out.println(); // descending 
  }
}

--

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop\no-zoom
> run Example
 3.141592653589793 12.566370614359172 24.0 28.274333882308138 36.0
 36.0 28.274333882308138 24.0 12.566370614359172 3.141592653589793


Good luck with the interviews and see you next time. 

--