CS100J, Fall 2001 Thurs 11/15 Lecture 22 ------------------------------------------------------------------------------- Announcements: + T3 on 11/20 (no, I didn't pick this day, but I can't really change it) + P6 posted + E9 due 11/27 (draw inheritance hierarchy for P6, including makeup portion) ------------------------------------------------------------------------------- Topics: + $super$ to access superclass member + information hiding and inheritanace + $static$, $final$ and inheritance ------------------------------------------------------------------------------- Summary from previous lectures: + public methods are called from type of object + public fields are called from type of a reference variable + subclass constructor must call either another constructor of the same class (using this(...)) or the superclass constructor (using super(...)). Ultimately, a subclass constructor must call the superclass constructor. + public members (which are not constructors) inherit, which means public fields and methods are essentially "copied" into the subclass, which also means Java will use the members as if they were written in the subclass + methods call fields (variables) from class in which method is written + overriding means method with same header called in subclass, not superclass + never use variable shadowing, which means writing the same field in both a sub and superclass ------------------------------------------------------------------------------- Inheritance & Information hiding: + more uses of $super$ + data hiding with subclasses + reminder on info hiding: - protect class against accidents/deliberate attacks - helps debugging and working with teams ------------------------------------------------------------------------------- $super$ + super(...) calls the constructor of a superclass + super.member calls the member of the superclass to use the "previous" (superclass) version instead of the inherited version - provides a way of using an overriden method - not really for fields, because you're supposed to avoid shadowing Example) public class inherit_super { public static void main(String[] args) { new B().print(); } } class A { public void print() { System.out.println("A"); } } class B extends A { public void print() { super.print(); System.out.println("B"); } } // Output? ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Information hiding: + $public$: - least restrictive - member is inherited and visible + $private$: - most restrictive - inaccessible to other classes - sometimes referred to as "not inherited", but some authors hate that (sometimes also called "not defined" or "not accessible" - use inherited code to access a private member from "above" + $protected$ (see Appendix 5 Savitch) - inherited and visible to all subclasses from a superclass (acts as if were public to subclasses) - visible within a package - visible to any subclass regardless of package + default ("blank") (see Appendix 5 Savitch) - visible within a package (collection of classes, Savitch pp 364-367) - not visible to any class OUTSIDE of package, including subclasses + Recommendations: - ____________ : need something visible ONLY within the scope of a class - ____________ : need something visible within a "chain" of classes, but not to outside classes - ____________ : need something visible everywhere + Changing accessibility in subclass? (overriding, shadowing) - can't make *method* modifiers more restrictive! - _________ > _________ > _________ > _________ - see Table 3.1 in "Java in a Nutshell" - what about fields? (they can be shadowed, which means allowing different access) - inherit_access2.java Example of basic modifiers) public class inherit_access { public static void main(String[] args) { new B(); } } class A { public int w = 1; protected int x = 2; /*default*/ int y = 3; private int z = 4; } class B extends A { B() { System.out.println(w); System.out.println(x); System.out.println(y); // System.out.println(z); } } // output: ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- How to access "uninherited" members? + can't DIRECTLY access a member with $super.member$ + use non-$private$ members to access the "uninherited" members - Java keeps the "non-inherited" members in memory in the subclass - a public member that's in the same class as the private member can access that private member Example) public class inherit_super3 { public static void main(String[] args) { new B(1).print(); } } class A { private int x; public A(int x) { this.x = x; } public void print() { System.out.println(x); } } class B extends A { public B(int x) { super(x); } public void print() { // How to print the value of x? } } ------------------------------------------------------------------------------- What about overriding for private members? Example) Inherited methods are used to access hidden fields: public class inherit_super4 { public static void main(String[] args) { System.out.println(new B(4).getX()); } } class A { private int x=1; public A(int x) {this.x = x;} public int getX() {return x;} } class B extends A { public B(int x) { super(x); } // Which version(s) work(s)? // Version 1: // public int getX() { return x+1; } // Version 2: // public int getX() { return super.getX()+1; } // Version 3: no overriding of getX } ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- More complications with private methods: + private methods are "bound" to first occurrence: RULE 5: a call to a private superclass method is bound to the implementation in the superclass - translation: a subclass cannot call a private method, so Java will use the superclass version, even if it appears as if the subclass overrides the definition - "appears to override?" actually, no overriding allowed for private methods! public class inherit_private { public static void main(String[] args) { new B(); } } class A { private int x; public double y; public A() { print1(); print2(); print3(); print4(); } private void print1() { System.out.println(x+1); } private void print2() { System.out.println(x+2); } public void print3() { System.out.println(x+3); } private void print4() { System.out.println(x+4); } } class B extends A { public B() { System.out.println("--"); /* print1(); */ print2(); print3(); print4(); } public void print2() { System.out.println(y+1); } // private void print3() { System.out.println(); } private void print4() { System.out.println(y+2); } } // Output? ------------------------------------------------------------------------------- $static$ (see inherit_static.java) + inherits, but cannot be overriden or shadowed + $static$ methods and varibles always accessed with reference type ------------------------------------------------------------------------------- $final$: + variables: cannot reassign + classes: cannot extend + methods: cannot override // Java cannot change a final variable: public class inherit_final { public static void main(String[] args) { final int x = 1; x = 2; // fails } } // Java cannnot extend a $final$ class: final class A {} class B extends A {} // fails // Java cannot override a $final$ method: class C { public final void blah() {} } class D extends C { public void blah() {} // fails } -------------------------------------------------------------------------------