Lecture 26 11/28
Inheritance, Polymorphism

Inheritance & Encapsulation:
+ $private$
  - prevents subclass from seeing/directly accessing the member
  - sometimes referred to as "prevents inheritance", but some authors hate that
  - sometimes also called "not defined"
+ $protected$
  - acts like $private$ for outside classes
  - still allows subclasses to see/use $member$
+ $public$ and default:
  - allows subclasses to see/use $member$

//-------------------------------------------------------------------------
// INHERIT3
class A {
    private     int w = 1;
    protected   int x = 2;
    public      int y = 3;
    /*default*/ int z = 4;
}
class B extends A {
    B() {
	super();
	// System.out.println(w); // doesn't inherit/also called not defined
	System.out.println(x);
	System.out.println(y);
	System.out.println(z);
    }
}
public class inherit3 {
    public static void main(String[] args) {
	B b = new B();
    }
}
// output: 2 3 4
//-------------------------------------------------------------------------

methods
+ also inherit (if not $private$)
+ often used to access $private$ members that the subclass cannot "see"
+ acts on information of current class

//-------------------------------------------------------------------------
class A {
    private int x=1;
    A(int x) {this.x = x;}
    public int get_x() {return x;}
}
class B extends A {
    B(int x) { super(x); }
}
public class inherit4 {
    public static void main(String[] args) {
	System.out.println(new B(4).get_x());
    }
}
// output: 4
//-------------------------------------------------------------------------

method overriding
+ subclass has method with same signature as one in superclass
+ body is different
+ Java calls subclass's version of the method
  (when method looks like it's calling superclass version, Java will
   indeed call version from subclass)
+ cannot declare inherited member to be MORE private than superclass member
  Privacy scale:
  private > protected > default > public

//-------------------------------------------------------------------------
// INHERIT5
class A {
    protected int x=1;
    A(int x) { this.x = x; get_x(); }
    public void get_x() { System.out.println("A: "+x); }
}
class B extends A {
    B(int x) { super(x); }
    public void get_x() { System.out.println("B: "+x); }
}
public class inherit5 {
    public static void main(String[] args) {
	new B(5).get_x();
    }
}
// output:
// B: 5
// B: 5
//-------------------------------------------------------------------------

Accessing superclass code:
+ use $super$:
  - can use in all non-static methods of subclass
  - acts reference to current object as instance of superclass
+ kind of like accessing a superclass member

// INHERIT6
class A {
    protected int x;
    A(int x) { this.x = x; }
    public void get_x() { System.out.println("A: "+x); }
}

class B extends A {
    B(int x) { super(x); }
    public void stuff() { 

	// $super$ treats the current object as an instance of $A$

	get_x();        // current object: use class $B$
	super.get_x();  // current object: use class $A$

	super.x = 2;    // current object: use class $A$

	get_x();        // current object: use class $B$
	super.get_x();  // current object: use class $A$
    }

    public void get_x() { System.out.println("B: "+x); }
}

public class inherit6 {
    public static void main(String[] args) {
	new B(1).stuff();
    }
}

/*
B: 1
A: 1
B: 2
A: 2
*/
//-------------------------------------------------------------------------

$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
  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

// INHERIT7: Object class

class A {
    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 inherit7 {
    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

    }
}