Summary
Subtype relationship
- child class is a subtype of the parent
java
class P {
}
class Q extends P {
}
class R extends Q {
}
Super
- calls the constructor of the parent class
- access methods in the parent class, that may have been overridden
java
class Parent {
Parent() {
}
}
class Child extends Parent {
Child() {
super(); // construct the parent class
}
}
Final
- prevents user from inheriting from the class
java
final class Parent {
}
class Child extends Parent { // not possible to inherit
}
Protected
- child class cannot access private fields in the parent class
- protected allows this
- avoid using protected for #cs2030s
java
class Parent {
private int a; // cannot be accessed outside Parent
protected int b; //
}
class Child extends Parent { // not possible to inherit
}
Concept
Every class in java extends from the base java.lang.Object class
Creating a subclass of another class
- ‘is-a’ relationship
- that has the same base functionality as the parent with more added
- ie. the Square and Circle classes can be the child class of the Shape class
Type casting
- to mimick a narrowing type conversion, mainly at run-time
- succeeds at compile-time when the CTT of the variable is related to type its being cast to
- succeeds at run-time when the RTT of the variable is a subtype of the type its being cast to
Application
Run-time errors when type casting, see casting to interfaces
java
interface A { }
abstract class B implements A { }
interface C { }
class D extends B implements C { }
class E implements A { }
A a = new E();
B b = new D();
C c = new D();
D d = new D();
E e = new E();
a = d; // widening type conversion, D <: A
a = (B) d; // compiles: CTT(d) = D is related to B, runs: RTT(d) = D <: B
a = (B) a; // compiles: CTT(a) = A is related to B, run-time error: RTT(a) = E </: B
c = (C) e; // compiles: see interfaces. run-time error: RTT(e) = E </: C
b = (A) e; // compile-time error on "=": CTT((A) e) = A </: B, invalid narrowing type conversion
b = (D) e; // compile-time error: CTT(e) = E is not related to D
b = (D) a; // compiles: CTT(a) = A is related to D, run-time error: RTT(a) = E </: D
// # 1
b = (B) a; // compiles: CTT(a) = A is related to B, run-time error: RTT(a) = E </: B
// # 2
b = (B) e; // compile-time error: CTT(e) = E is not related to B
// # 3
b = (D) b; // compiles: CTT(b) = B is related to D, runs: RTT(b) = D <: D
// # 4
b = (B) d; // compiles: CTT(d) = D is related to B, runs: RTT(d) = D <: B
from examples 1 & 2, we see that the compile time check only checks the declared type
from examples 3 & 4, we see that the compile time check only checks if the types are related
3D and 2D point
java
class Point2D {
private double x;
private double y;
public Point2D(double x, double y) {
this.x = x;
this.y = y;
}
public double distanceTo(Point2D p) {
double hori = this.x - p.x;
double vert = this.y - p.y;
return Math.sqrt((hori * hori) + (vert * vert));
}
class Point3D extends Point2D {
private double z;
public Point3D(double x, double y, double z) {
super(x, y); // construct the parent 2D point
this.z = z;
}
public double flatDistance(Point3D p) {
return super.distanceTo(p); // works since Point3D <: Point2D
}
}