CS 160 Lecture 4
Subclasses and Inheritance
Composition and Inheritance
Java provides two ways of using existing classes to create new ones. One is composition, in which a class definition has an object of another class as one of its data members. For example, a class representing a course section at Oberlin College might have a definition like this:class CourseSection {
String name;
int CRN;
int creditHours;
Department department;
Instructor instructor;
Student[] students;
}
Classes related by composition form a has-a relationship. A section has an instructor, has a set of students, etc.
Another way to use a class is to extend it by inheritance . The idea is that we can modify a class by specializing it to a subclass.
example. Vehicle --> SUV --> Explorer
You may have noticed the use of RuntimeException and IOException in lab 1. These are extensions of Java's Exception class, specialized to represent particular types of exception.
A point of terminology: When class B extends class A, we say that B is a subclass of A and that A is the superclass of B. A class may have only one superclass. We also say that A is a base class and B is a derived class.
Classes related by inheritance form an is-a relationship. For example, a RuntimeException is a (special type of) Exception. The distinction between has-a and is-a is probably the best guide to a software designer in deciding whether to use composition or inheritance in a given situation. (There are some situations, however, when either composition or inheritance may be used.)
Extending a class
Technically, when a class is extended by inheritance, three types of extension are possible:- Adding additional instance variables.
- Adding additional instance methods.
- Overriding an instance method; that is, replacing a method of the superclass with a method specific to the subclass.
class Obie {
String name;
String ssn;
String Tnumber;
void changeAddress(){
}
}
class StudentObie extends Obie {
int graduationYear;
double gpa;
void register(Course course){
}
void graduate(){
}
}
class FacultyObie extends Obie {
String position;
String department;
void retire(){
}
}
The Object Hierarchy
The extends relationship imposes a hierarchy, or tree structure, on Java classes. For example, GUI components are all subclasses of Component, which itself is a subclass of Object.Java defines a class called Object which is the root of the tree. Every class definition which does not explicitly extend another class, implicitly extends Object. So, every class (except Object) has a superclass from which it inherits. Among the methods that every class inherits, directly or indirectly, from Object are
boolean equals (Object);These methods are often overridden in a class definition to code that is specific to the class. However, it means that every Java object can respond to a toString message.
String toString();
Assignment compatibility
Consider the following class hierarchy
Q: If we have a variable of type SUV, can we store an Explorer object in it? That is, could we write
SUV suv = new Explorer();A: Yes because an Explorer is an SUV (albeit a special type of SUV).
Q: What if we try to do this in reverse:
Explorer exp = new SUV();A: We get an error. We cannot store an SUV object in an Explorer variable.
Some implcations of this:
- If we have an array of SUVs defined by
SUV suv[] = new SUV[50];
we could store Explorers, Cherokees, 4Runners, etc. in the array.
- If we have a method that expects an SUV as a parameter, we can pass an Explorer object to it.
One result of this is a potential ambiguity. Suppose that SUV has a "drive" method, which is overridden by Explorer. Suppose we say
SUV suv = new Explorer();then
suv.drive();Which drive method is called, SUV's drive method or Explorer's drive method?
example illustrating type casting