Here's what we know so far: 

Horse = { talk() } 

and 
   
Unicorn = Horse U { sing() }

In code: 

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

class Unicorn extends Horse {
  void sing() {
    System.out.println( "Some-wheeeeeere overtheraaaa-aaainbow etc." )
  } 
}

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

Let me first show you how something like this is used in Java: 

class One extends javax.swing.JFrame {
  One(int w, int h) {
    this.setSize(w, h); 
    this.setDefaultCloseOperation( 3 ); // really, EXIT_ON_CLOSE
    this.setVisible(true); 
  } 
  public static void main(String[] args) {
    One a = new One(Integer.parseInt(args[0]), Integer.parseInt(args[1])); 
  } 
}

In this example the JFrame is the Horse and we are define a Unicorn (the Something class). 

Now let's go back to the code we started from: 

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

class Unicorn extends Horse {
  void sing() {
    System.out.println( "Some-wheeeeeere overtheraaaa-aaainbow etc." );
  } 
}

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

Questions: 

(a) can a Unicorn talk? 

Answer: yes, by inheritance. 

(b) is a Unicorn a Horse? 

Answer: yes, by polymorphism. 

(c) is a Horse a Unicorn? 

Answer: no.

(c) can a Unicorn talk in another language (e.g., in French)? 

Answer: yes. 

You can define a new talk inside the class. 

(d) can a Unicorn still speak in English even if it learns French? 

Answer: yes, using super.talk();

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


class Unicorn extends Horse {
  void sing() {
    System.out.println( "Some-wheeeeeere overtheraaaa-aaainbow etc." );
  } 
  void talk() {
    super.talk(); 
    System.out.println( "Bonjour." ); 
  }
}

class Example {
  public static void main(String[] args) {
    Horse a = new Horse(); 
    a.talk(); 
    Unicorn b = new Unicorn(); 
    b.talk(); 
    b.sing(); 
    // is a Unicorn a Horse?
    Horse u = new Unicorn(); // a Unicorn is a Horse
    u.talk(); 
    ((Unicorn) u).sing(); // can't ask u.sing(); 
    // is a Horse a Unicorn? 
    // no, and that's why Unicorn m = new Horse(); is not allowed 
    Unicorn x = new Unicorn(); 
    x.talk();
  }
}


Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop
> run Example
Howdy.
Howdy.
Bonjour.
Some-wheeeeeere overtheraaaa-aaainbow etc.
Howdy.
Bonjour.
Some-wheeeeeere overtheraaaa-aaainbow etc.
Howdy.
Bonjour.


Next, let's look through this: 

http://www.cs.indiana.edu/classes/a201-dger/sum2004/notes/Eleven.html

Then through this: 

http://www.cs.indiana.edu/classes/a201-dger/sum2002/notes/TwentyEight.html

Then let's extract this rule and ponder it:

  Constructor Chaining

  When you define a class, Java guarantees that the class's constructor method 
  is called whenever an instance of that class is created. It also guarantees 
  that the constructor is called when an instance of any subclass is created. 
  In order to guarantee this second point, Java must ensure that every constructor 
  method calls its superclass constructor method. If the first statement in a constructor 
  is not an explicit call to a constructor of the superclass with the super keyword, then 
  Java implicitly inserts the call super() -- that is, it calls the superclass constructor 
  with no arguments. If the superclass does not have a constructor that takes no arguments, 
  this causes a compilation error.

  There is one exception to the rule that Java invokes super() implicitly if you do not do so
  explicitly. If the first line of a constructor, C1, uses the this() syntax to invoke another
  constructor, C2, of the class, Java relies on C2 to invoke the superclass constructor, and 
  does not insert a call to super() into C1. Of course, if C2 itself uses this() to invoke a 
  third constructor, C2 does not call super() either, but somewhere along the chain, a 
  constructor either explicitly or implicitly invokes the superclass constructor, which 
  is what is required.

  What this all means is that constructor calls are "chained" -- any time an object is created, 
  a sequence of constructor methods are invoked, from subclass to superclass on up to Object at 
  the root of the class hierarchy. Because a superclass constructor is always invoked as the 
  first statement of its subclass constructor, the body of the Object constructor always runs 
  first, followed by the body of its subclass, and on down the class hierarchy to the class that 
  is being instantiated. 

Let's see what that means. 

Let's start our Horse/Unicorn example again. 

But this time we include some instance variables in the Horse model: 

class Horse {
  String name;
  Horse(String name) {
    this.name = name; 
  } 
  // ... what else? 
}

Let's build a Unicorn now, from that.

class Horse {
  String name; 
  Horse(String name) {
    this.name = name;  
  }
  void talk() {
    System.out.println("I am a Horse with the name " + this.name);  
  }
}

class Unicorn extends Horse {

}

This combination won't compile because it's equivalent to: 

class Unicorn extends Horse {
  Unicorn() {
   
  }
}

This combination won't compile because in turn it is equivalent to: 

class Unicorn extends Horse {
  Unicorn() {
    super(); 
  }
}

This doesn't compile because there is no no-arg constructor in the super class. 

Here's what might work:

class Unicorn extends Horse {
  Unicorn() {
    super("No Name"); 
  }
}

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

Here's also what might work: 

class Unicorn extends Horse {
  Unicorn(String name) {
    super(name); 
  }
}

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

Here's what this produces: 

Welcome to DrJava.  Working directory is C:\Users\dgerman\Desktop
> run Example
I am a Horse with the name Ted
I am a Horse with the name Samuel


Exercises are due Fri, try to submit them as soon as possible though. 

--