Lecture 25 11/21
Inheritance

Background
+ takes time to write classes
+ sometimes classes resemble/copy code from other classes
+ want to save time
+ software reuse
+ solution: use INHERITANCE

Inheritance
+ derive a class from another
+ essentially, copy code without having to rewrite code
+ theory: class B is a class A
+ example: Student is a Person
+ Terms:
  B: subclass/derived class/child class (more specific)
  A: superclass/base class/parent class (more general)
+ is-a relationships mean you should use inheritance
+ use $extends$
  class _subclassname_ extends _superclassname_ { stuff }

//-------------------------------------------------------------------------
// INHERIT0
// The following code is an example of a hierarchy that classes might form.

class A {}
class B extends A{}
class C extends A{}
class D extends B{}

// Here is the Class Hierarchy:
//
//         A
//        / \
//       B   C
//       |
//       D
//
// Note how you write superclasses above subclasses.
// A superclass may have multiple subclasses,
// but each subclass may have only ONE superclass.

public class inherit0 {
    public static void main(String[] args) {
    }
}
//-------------------------------------------------------------------------

What happens?
+ code from A is inherited by B
+ you create an object from B, but that object uses code from A
+ no object from A is created!
+ it is as if you wrote the code from A in B, but didn't to save time

//-------------------------------------------------------------------------
// INHERIT1
class A { int x = 1; }
class B extends A {}

public class inherit1 {
    public static void main(String[] args) {
	B b = new B();
	System.out.println(b.x);
    }
}
// output: 1
//-------------------------------------------------------------------------

General rules:
+ constructors NEVER inherit
+ subclass must call constructor of superclass:
  use $super$(_arguments_)
  must match one constructor of super class
  must be first line of code in the subclass constructor
+ if no constructor written in sub class:
  default constructor used
  $super()$ called automatically

//-------------------------------------------------------------------------
// INHERIT2
class A {
    int x;
    A(int x) {this.x=x;}
}
class B extends A {
    B(int x) {super(x);}
}
public class inherit2 {
    public static void main(String[] args) {
	B b = new B(2);
	System.out.println(b.x);
    }
}
// output: 2
//-------------------------------------------------------------------------

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)

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

To come:
+ $static$
+ indirect access with methods
+ $super$._member_
+ $Object$
+ polymorphism