Java programs are made out of classes.

No classes -- no programs. 

A class is a container: 

  it contains static members, 

  it also contains a blueprint, to create objects. 

Inheritance, interfaces, abstract classes. 

I can start modeling right away: 

class Register {

}

Here's an example of how I can make instances: 

class Story {
  public static void main(String[] args) {
    Register a, b = new Register();
    a = new Register(); 
    System.out.println( a ); 
    System.out.println( b ); 
    Register[] r = new Register[10]; 
    for (int i = 0; i < r.length; i++) 
      r[i] = new Register();
    int count = 0; 
    for (Register register : r) { 
      System.out.println( count + ". " + register ); 
      count += 1; 
    }
  }
}

Here's the output if we compile and run the code above: 

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop
> run Story
Register@7732d4
Register@8b170e
0. Register@96cb44
1. Register@1b110e4
2. Register@4214de
3. Register@9eb61a
4. Register@1ce757c
5. Register@42b174
6. Register@e7a30e
7. Register@930dae
8. Register@12ca201
9. Register@e1fc0d


With this we introduced the first rule: 

  (a) if you don't have any constructor you will be given one. 

So if you write: 

class Register {

}

You actually have this: 

class Register {
  Register() {
    
  }
}

Normally you would model because you want to place some features in your instances. 

Here's what my Registers can do for now: talk(). 

class Register {
  public void talk() {
    System.out.println("I am a Register named: " + this);  
  }
  public static void main(String[] args) {
    Register a, b = new Register();
    b.talk(); 
    a = new Register();
    a.talk(); 
    System.out.println( a ); 
    System.out.println( b ); 
  }
}

The output is: 

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop
> run Register
I am a Register named: Register@282de2
I am a Register named: Register@90aa82
Register@90aa82
Register@282de2


Each object can refer to its unique self by keyword: this.

Now let's define something useful: points on the screen. 

class Point {
  public String report() { // toString
    return "I am a Point " + this; 
  }
  public static void main(String[] args) {
    Point a = new Point();
    System.out.println( a ); 
    System.out.println( a.report() ); 
  }
}

I tried but could use the name toString() for instance method report. 

I add instance variables: x, y. 

class Point {
  int x, y; 
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  public String report() { // toString
    return "I am a Point " + this; 
  }
  public static void main(String[] args) {
    Point a = new Point(3, -2);
    System.out.println( a ); 
    System.out.println( a.report() ); 
  }
}

I lost the no-arg constructor but I also don't need it. 

You get a default constructor only when you don't specify any. 

So we ended with:

class Point {
  int x, y; 
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  Point () {
    this(0, 0); // call the other constructor with initial values 0 and 0 
  }
  public String report() { // toString
    return this + " is a Point at (" + this.x + ", " + this.y + ")"; 
  }
  public double distanceTo(Point other) { // new method here 
    int dx = this.x - other.x; 
    int dy = this.y - other.y; 
    return Math.sqrt( dx * dx + dy * dy ); 
  }
  public static void main(String[] args) {
    Point a = new Point(3, -2);
    System.out.println( a ); 
    System.out.println( a.report() ); 
    System.out.println( a + " is a point at (" + a.x + ", " + a.y + ")" );
    Point b = new Point();
    System.out.println( b.report() ); 
    System.out.println( a.distanceTo(b) ); // test in main for new method 
  }
}

One more thing and we introduce a new topic: 

class Point {
  static Point origin = new Point(0, 0); // difference between static and non-static members
  int x, y; 
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  Point () {
    this(0, 0); // call the other constructor with initial values 0 and 0 
  }
  public String report() { // toString
    return this + " is a Point at (" + this.x + ", " + this.y + ")"; 
  }
  public double distanceTo(Point other) { // new method here 
    int dx = this.x - other.x; 
    int dy = this.y - other.y; 
    return Math.sqrt( dx * dx + dy * dy ); 
  }
  public static void main(String[] args) {
    Point a = new Point(3, -2);
    System.out.println( a ); 
    System.out.println( a.report() ); 
    System.out.println( a + " is a point at (" + a.x + ", " + a.y + ")" );
    Point b = new Point();
    System.out.println( b.report() ); 
    System.out.println( a.distanceTo(b) ); // test in main for new method 
    
    double distance; 
    distance = Point.origin.distanceTo( new Point(3, 4) ); // like System.out.println
    System.out.println( distance ); 
    
  }
}

The output is:

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop
> run Point
Point@d79cbb
Point@d79cbb is a Point at (3, -2)
Point@d79cbb is a point at (3, -2)
Point@2469a6 is a Point at (0, 0)
3.605551275463989
5.0


Please e-mail this to me as your attendance (at dgerman@indiana.edu)

And now let's talk about the class extension mechanism.     

Horse = { talk() }

Unicorn = Horse U { sing() } 

The class extension mechanism is just the set union of features.

class Horse {
  void talk() {
    System.out.println( " I am a Horse. " ); 
  } 
}

class Unicorn extends Horse {
  void sing() {
    System.out.println( " I am singing... ");  
  }
}

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

Compile and run this last program and you get: 

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop
> run Example
 I am a Horse. 
 I am a Horse. 
 I am singing... 


This is the starting point of the lab today. 

The class extension mechanism leads into the following phenomena:

(a) inheritance (already shown above with method talk() for Unicorns)
(b) polymorphism
(c) dynamic method lookup, 
(c) and constructor chaining. 

We will explore/define/explain these in lab, then you will have to solve some exercises. 

See you in lab. 

Summary: 

  (a) every class comes with a blueprint in it
  (b) a blueprint can be instantiated with new 
  (c) constructors are blueprint initialization procedures
  (d) if you don't specify any constructor you get a default no-arg constructor
  (e) if you specify a least one constructor you're not in default mode any more
  (f) this is a keyword, it is used by an object as reference to itself
  (g) you can call one constructor from the other if you use this(...)

With this we're ready for the lab.

--