Computer Science 15-111 (Sections A & B), Spring 2007

Class Notes:  16-Feb-2007 + 19-Feb-2007

 

Logistics

  1. Test 1 is on Wed 21-Feb-07.  It is worth 10% of your semester grade.
    Covers everything up to and including Wed 14-Feb-07, including:
    1. Chapters 1-6
    2. Appendices A.1, A.3, B.1, B.2
    3. Homeworks 1 – 5
    4. All lectures and recitations
  2. For weighting purposes, hw1 will be combined with hw2.

Topic Outline:

1.      Import static
import static java.lang.System.out;
...
out.println("Look, no System.  Wow!");

2.      Inheritance:  Why?

a.      Example:  IntroCsApplication and IntroCsComponent

b.      Example:  Swing Class Hierarchy


3.   Overriding Instance Methods
  import static java.lang.System.out;

  class Vehicle {
   public String honk() { return "honk"; }
  }
  class Car extends Vehicle {
    // Car inherits honk() method from Vehicle!
  }
  class Truck extends Vehicle {
    // Truck overrides honk() method from Vehicle!
    public String honk() { return "HONK! HONK!"; }
  }
  class Main {
    public static void main(String[] args) {
      Vehicle v1 = new Car();
      Vehicle v2 = new Truck();
      out.println(v1.honk()); // "honk"
      out.println(v2.honk()); // "HONK! HONK!"
    }
  }


4.      Polymorphism
Same type (Vehicle), same method call (“honk()”), different code!
    public static void main(String[] args) {
      Vehicle v;
      v = new Car();
      out.println(v.honk()); // "honk"
      v = new Truck();
      out.println(v.honk()); // "HONK! HONK!"
    }

5.   Calling Overridden (super) Methods
  class AnnoyingCar extends Car {
  public String honk() {
        StringBuilder sb = new StringBuilder();
        sb.append(super.honk());
        sb.append(" ");
        sb.append(super.honk());
        sb.append(" ");
        sb.append(super.honk());
        return sb.toString();
  }
  }
  class Main {
    public static void main(String[] args) {
      Vehicle v;
      v = new AnnoyingCar();
      out.println(v.honk()); // "honk honk honk"
    }
  }

6.      Overriding  !=  Overloading
  import static java.lang.System.out;
  class Vehicle {
    public String honk() { return "honk"; }
    // overloads honk()
    public String honk(boolean loudly) {
        String honk = this.honk();
        if (loudly) honk = honk.toUpperCase();
        return honk;
   }
  }
  class DrSeussicle extends Vehicle {
    // overrides honk()
    public String honk() { return "hawoooga"; }
  }
  class Main {
    public static void main(String[] args) {
      Vehicle v = new DrSeussicle();
      out.println(v.honk());     // "hawooga"
      out.println(v.honk(true)); // "HAWOOGA"
    }
}



7.      Inheriting Instance Variables

a.      Not an issue for us, as we always make our instance variables private

b.      Have subclasses use accessors (getValue()) and mutators (setValue())

c.      Subclasses can override accessors and mutators, if need be

d.      If you really must give a subclass access to a superclass’s instance variables, make them protected or default instead of private, and provide a clear comment as to why this was absolutely necessary.

8.      Inheriting Static Variables and Methods
Not an issue for us, because we qualify our static variables and methods with the class where they are defined!

9.      Calling a Superclass’s Constructor (with “super()”)
   import static java.lang.System.out;
   class Cat {
        public Cat() { this(false); }
        public Cat(boolean likesWater) {
           out.println("Cat("+likesWater+")");
        }
   }
   class HouseCat extends Cat {
        // default constructor
        // implicit:  public HouseCat() { super(); }
   }
   class Lion extends Cat {
        public Lion() {
             // implicit:  super();
             out.println("Lion");
        }
   }
   class Tiger extends Cat {
        public Tiger() {
             super(true);// explicit call to superclass constructor
             out.println("Tiger");
        }
   }
   class Main {
        public static void main(String[] args) {
             Cat cat1 = new HouseCat(); // Cat(false)
             Cat cat2 = new Lion();     // Cat(false) Lion
             Cat cat3 = new Tiger();    // Cat(true) Tiger
        }
   }


10.  Conundrum:  Subclass Methods Are Not Visible to Superclass

     Object s = "Hello";

     out.println(s.length());            // Will not compile!
     out.println(((String)s).length());  // 5


 

11.  Conundrum continued:  Superclass Cannot See Subclass Methods Even if All Subclasses Implement Them!
  import static java.lang.System.out;
  class Vehicle {
  }
  class Car extends Vehicle {
    public int getWheels() { return 4; }
  }
  class Truck extends Vehicle {
    public int getWheels() { return 18; }
  }
  class Main {
    public static void main(String[] args) {
      Vehicle v;
      v = new Car();
      out.println(v.getWheels()); // Will not compile!
      v = new Truck();
      out.println(v.getWheels()); // Will not compile!
    }
  }


12.  Conundrum Solution #1:  Implement the Method in the Superclass
    plus        Easy!
    minus    Superclass method must do something, but what?
                  So this approach can be quite misleading.

  import static java.lang.System.out;
  class Vehicle {
    public int getWheels() {
        // this is bogus, but what value makes sense
        // for a generic vehicle?

        return 0;
    }
  }
  class Car extends Vehicle {
    public int getWheels() { return 4; }
  }
  class Truck extends Vehicle {
    public int getWheels() { return 18; }
  }
  class Main {
    public static void main(String[] args) {
      Vehicle v;
      v = new Car();
      out.println(v.getWheels()); // 4  (works now!)
      v = new Truck();
      out.println(v.getWheels()); // 18 (works now!)
    }
  }



13.  Conundrum Solution #2:  Abstract Class
    plus        Elegant!
    minus    You cannot instantiate an abstract class.
                  Usually, this is desirable, but other times, this is too limiting.

  import static java.lang.System.out;
  abstract class Vehicle {
    // abstract method has no body!
    abstract public int getWheels();
  }
  class Car extends Vehicle {
    public int getWheels() { return 4; }
  }
  class Truck extends Vehicle {
    public int getWheels() { return 18; }
  }
  class Main {
    public static void main(String[] args) {
      Vehicle v;
      v = new Car();
      out.println(v.getWheels()); // 4  (works now!)
      v = new Truck();
      out.println(v.getWheels()); // 18 (works now!)
    }
  }


14.  Abstract Classes (continued)

a.      Declare the class itself as abstract.

b.      Define some methods but not others.

c.      Declare undefined methods as abstract

d.      Cannot instantiate an abstract class (what code should run for abstract methods?).

e.      Must subclass the abstract class, define all abstract methods, then instantiate this non-abstract class.

15.  The instanceof Operator  (Or, how can you test if a Vehicle is a Truck?)
   import static java.lang.System.out;
   class Vehicle { }
   class Truck extends Vehicle { }
   class Car extends Vehicle { }
   class Main {
         public static void main(String[] args) {
               Vehicle v;
               v = new Truck();
               out.println(v instanceof Vehicle); // true
               out.println(v instanceof Truck);   // true
               out.println(v instanceof Car);     // false
         }
   }


 


16.  The getClass() method  (Or, how can you find the type of a Vehicle in one step?)
   import static java.lang.System.out;
   class Vehicle { }
   class Truck extends Vehicle { }
   class Car extends Vehicle { }
   class Main {
         public static void main(String[] args) {
               Vehicle v;
               v = new Truck();
               out.println(v.getClass().getName()); // "Truck"
               v = new Car();
               out.println(v.getClass().getName()); // "Car"
               String s = "Go Tartans!";
               out.println(s.getClass().getName()); // "java.lang.String"
         }
   }


17.  Inheritance vs. Composition / Delegation:   “is-a”  versus  “has-a”

a.      Inheritance:  Car is-a Vehicle, and inherits “capacity”, “mileage”, other properties.

b.      Composition:  Car has-a Radio instance, and delegates “play”, “changeStation”, to the radio instance.