Computer Science
15-111 (Sections A & B), Spring 2007
Class Notes: 16-Feb-2007 + 19-Feb-2007
Logistics
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.