CS100J, Fall 2001 Thurs 11/8 Lecture 20 ------------------------------------------------------------------------------- Announcements: + E8 due Tues + T3 on 11/20 - everything up to and including 11/13 - Topics: strings/chars, searching/sorting, arrays, some inheritance + reminder of reading: Chap 7, 10.1 ------------------------------------------------------------------------------- Topics: + software reuse + fundamentals of OOP + inheritance: - "is-a" and sub/super class relationship - $extends$ keyword - inheritance of public members - rules for constructors ------------------------------------------------------------------------------- Summary so far: + Programming: automated problem solving + Writing Process: brainstorm, research, outline, draft, polish, test + Drafting: stubbing, stepwise refinement, top-down, bottom-up, reuse + Pedogogy: remove redundancy expressions -> flow control -> methods -> objects -> arrays -> ??? + What's next? removing redundancy in writing classes (expand reuse notion) + OOP: encapsulation, inheritance, polymorphism ------------------------------------------------------------------------------- Software reuse: + removing redundancy in writing classes to save time + example: - think about class Person, Worker, Rower, Student, .... - they're all related! + remove redundancy? 2 choices: 1) manually copy/paste code 2) automatically copy/paste code How? Use INHERITANCE. ------------------------------------------------------------------------------- Inheritance: + reuse previously written classes with minimal amount of rewriting code + allow language to automatically "borrow" class members + need to develop "tree" of classes to know which borrows from another.... ------------------------------------------------------------------------------- Developing an inheritance structure: (1) Think of classes that represent general categories (2) Think of classes that represent specific versions of those generalities (3) Try to identify if one class IS A type of another class (4) If you're unsure of the relationship: - see if a class CAN BE a type of the another class - see if EVERY class is a type of another Example) A Ford is a Car. But, not every Car is a Ford. Car <========= general Ford <========= specific Notes) IS-A relationships are *not* HAS-A relationships! + HAS-A: encapsulation + IS-A: inheritance ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Tree structure for organizing classes: + terminology: - general class: SUPERCLASS/base class/parent class - specific class: SUBCLASS/derived class/child class + tree/CLASS HIERARCHY: - draw superclasses "above" - draw subclasses "below" - connect with arrows pointing "up" + how many arrows? - single inheritance: *one* - multiple inheritance: *many* + Java: single inheritance! Example) Dining hall people: Person, Diner, Worker, Owner, Peon, StudentWorker, FullTimeWorker, Supervisor Relationships: A Worker is a Person. An Owner is a Worker. (But not every Worker can be an Owner.) and so forth.... ------------------------------------------------------------------------------- Java inheritance syntax ($extends$): + class SUBCLASS $extends$ SUPERCLASS { constructors, members } Example) A Penny is a Coin. class _______ {} class _______ extends _______ {} + To develop code for inherited classes: - identify composite nouns in a problem ("research" phase) - identify is-a relationships to find sub- and superclasses - develop hierarchy (tree) of stubbed-out classes (no members) - use has-a (encapsulation) to write members - allow inheritance to automatically copy the code from super- to subclasses ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Creating objects from subclasses: + syntax: basic: Subclass var = new Subclass(...) advanced: Superclass var = new Subclass(...) (see Savitch 478-479) + rules: - subclass object has type of the subclass and all of its ancestors - you can assign a subclass object to a superclass variable - to assign a superclass object to a subclass variable, you need a cast + terminology: - REFERENCE TYPE: class type of variable var - ACTUAL TYPE: class type used to create the object Example) Model numbers: An integer is a double, but no OOP! double conceptually, integer double x1 = 1.0; // double gets double double x2 = 2; // double gets int double x3 = (double) 2; // double gets (double) int int x3 = 3; // int gets int int x4 = (int) 4.0; // int gets (int) double Why? A double is "wider" than an int. Example) Wide and Thin: A ________ thing can hold a ________ thing. class Wide {} class Thin extends Wide {} public class test { public static void main(String[] args) { Wide x1 = new Wide(); // Wide gets Wide Wide x2 = new Thin(); // Wide gets Thin Wide x3 = (Wide) new Thin(); // Wide gets Thin Thin x4 = new Thin(); // Thin gets Thin Thin x5 = (Thin) new Wide(); // Thin gets Wide (won't run!) } } Why? The "wider" type can hold a more "narrow" type. Actual types? x1 and x5 have actual types of Wide. x2, x3, and x4 have actual types of Thin. Reference types? x1, x2, and x3 have reference types of Wide. x4 and x5 have actual types of Thin. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Inheriting $public$ members: + assume subclass does not have public members inside sub - in this case, public members are inherited, which means that Java "copies" the public members into the subclass - so, you may access $x$ and $getX$ from class B + RULE 1: Public members inherit if they don't appear in subclass. Example of Rule1: ================ class A { public int x; public int getX() { return x; } } class B extends A { } public class rule1 { public static void main(String[] args) { B test = new B(); test.x = 1; System.out.println( test.getX() ); } } // output: _____ + Questions: - does an object of class A get created? _____________ - does class A "get" a value of $x$? _____________ - where did the $x$ and $getX$ go? ___________ + Weaknesses to be addressed: - does not work for constructors, which are technically NOT members - what if subclass has fields and/or methods with same names as superclass? - what if members of superclass are $private$? ------------------------------------------------------------------------------- Constructors: + constructors NEVER inherit (not considered members of a class!) + subclass MUST call constructor of superclass + syntax: 1st line of subclass constructor must be $super$(args), $this$(args), or neither (which forces $super$() by default) (1) subclass constructor calls superclass constructor with $super$: - the supercalls MUST have a constructor that matches the arguments - use for setting values that are inherited/used by the subclass (2) subclass constructor calls a constructor in the SAME class with $this$: - constructors in the same class can call eachother with $this$(args) - the last constructor in the "chain" must call the superclass constructor (see (3) ). (3) subclass constructor calls $super$() by default: - happens when you do not write a $super$ or $this$ constructor call as the first line in the last subclass constructor that is called - if you wrote a non-empty constructor in the superclass, the superclass lost its default constructor (also called empty constructor) - if the superclass has NO empty constructor, you will get an error, so you need to ensure that the default constructor exists ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- // INHERIT2 (constructors) class A { public int x; public A(int x) { this.x=x; } } class B extends A { public int y; public B(int x) { super(x); this.y = x; } public B(int x,int y) { this(x); this.y = y; } } public class inherit2 { public static void main(String[] args) { B b1 = new B(1); System.out.println("1st: "+b1.x+" "+b1.y); B b2 = new B(2,3); System.out.println("2nd: "+b2.x+" "+b2.y); } } /* Output: */ /* Things to test: * - remove super(x) statement from class B constructor * - how to include a default constructor in class A */ ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- $Object$: + Every class in Java is a subclass of class $Object$. + don't usually write $extends Object$ in the class header, but you could: class Blah extends Object and class Blah mean the same thing! + $Object$ gives methods like $toString$ and $equals$ - for many of these methods, user must define method body for class - tells specific class how to handle the methods + where to find members of Object? - http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html - http://java.sun.com/j2se/1.4/docs/api/ + Example) Demostrate $toString$, $equals$, $clone$, and $getClass$. class A { public int x; public A(int x) { this.x = x; } public String toString() { return "x = " + x; } public boolean equals(A a) { return x == a.x; } public Object clone() { return new A(x); } } public class inherit17 { public static void main(String[] args) { A a1 = new A(1); A a2 = (A) a1.clone(); System.out.println(a1); // x = 1 System.out.println(a2); // x = 1 System.out.println(a1.equals(a2)); // true System.out.println(a1.getClass()); // class A } } ------------------------------------------------------------------------------- Rules for creating objects: + Java does the following when creating an object in this order: - allocate memory for the fields of the object (including inherited ones) - set ALL fields to default values ("zeros") - INVOKE each constructor in the chain of $this$ constructors (if necessary) (invoke now means to activate the constructor, but not execute the body) - invoke the superclass constructor (for more ancestors, all constructors are activated all the way "up") - all fields are initialized in the order that they're delared (top-down, then according to precedence/associativity) - the bodies of the constructors are activated from last to first (Java starts from Object and works its way back to the first constructor) + see inherit3.java -------------------------------------------------------------------------------