What We Will Cover
Illuminations
Homework Questions?
Homework Discussion Questions
- How difficult was it to work with enums?
- What type of sorting methods did people implement?
^ top
7.1: Introduction to Inheritance
Objectives
At the end of the lesson the student will be able to:
- Describe how inheritance is used in Java
- Use inheritance in your programs
- Inherit from Java's classes
|
^ top
7.1.1: Introducing Inheritance
Inheritance: the ability to define new classes from existing ones.
- Inheritance is one of the important ideas of object-oriented programming
- It lets you code a class that is based on another class
- When used correctly, inheritance can simplify the overall design
- As you will discover, Java uses inheritance extensively in its API
How Inheritance Works
- A class that is inherited from is called the superclass (a.k.a. base, parent)
- A class that inherits is called the subclass (a.k.a. derived, child)
- The subclass automatically contains all the variable and method definitions of the superclass
- In a subclass, you can define new member variables and methods not found in the superclass
- The two classes in the following diagram show how this works

- Here the superclass is a
JFrame in the javax.swing package
- You use a
JFrame to create a GUI window, which is called a frame
- The class has several public constants and methods used to set-up the
JFrame
- For instance,
setSize() lets you set the width and height of a JFrame
- In the
HelloFrame subclass you can use all the constants and methods inherited from JFrame
- In addition, you can add new fields, constants and methods
- The example has added constants and a constructor
- New fields, constants and methods are specific to the subclass
About the Diagram
- The first rectangular section of a class diagram contains the class name
- The second section describes the attributes (fields or variables)
- The third (bottom) section describes the operations (methods)
- A minus sign (-) marks attributes and operations that cannot be accessed by other classes
- A plus sign (+) marks attributes and operations that can be accessed by other classes
- Parameters are listed in parenthesis separated by commas
- The upward pointing arrow indicates inheritance
^ top
7.1.2: Class Hierarchies
- You can derive classes from derived classes
- Subclasses become superclasses for their descendants
- Child classes become parent classes in turn
- When you have multiple levels of subclasses, you create an inheritance hierarchy
- Classes higher in the hierarchy are called ancestor classes
- Classes lower in the hierarchy are called descendent classes
- A class can use the variables and methods of any of its superclasses
- For example, a
Frame uses the variables and methods provided by both Window and Container
- Note that inheritance describes an is-a relationship
- For instance: a
Dialog is a Window
- This is in contrast to the has-a relationship, where a class contains a reference to another class
Diagram Showing an Inheritance Hierarchy
- The following diagram shows some classes from the Java API
- From the diagram, you can see that a superclass may have more than one subclass
- For instance,
Window has two subclasses: Frame and Dialog

Another Way to Draw Inheritance
Designing with Inheritance
- Note in the inheritance diagram above that a
Frame is a type of Window
- When using inheritance in an application, it is important to keep "is a" in mind
- Make sure a subclass has an is-a relationship with the superclass
- A subclass must be a type of a superclass
- Which of the following are valid is-a relationships?
- Car ==> Vehicle
- Car ==> Motorcycle
- Student ==> Person
- Student ==> College
- Substitute the words "is a type of" for the arrow (==>)
^ top
7.1.3: Inheritance Example
- To deriving a new class from an existing one, you use the
extends clause
- Syntax:
[accessModifier] class SubclassName extends SuperclassName
A subclass can only extend one superclass
Java does not support multiple inheritance
Interfaces (discussed later) achieve much of the same effect
Example Superclass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class Person {
private String name;
public Person() {
name = "No name yet";
}
public Person(String initialName) {
name = initialName;
}
public String getName() {
return name;
}
public void setName(final String newName) {
name = newName;
}
public void printAttributes() {
System.out.println("Name: " + name);
}
public boolean sameName(Person other) {
return (name.equalsIgnoreCase(other.name));
}
private final void special() {
System.out.println("I am special");
}
}
|
Example Subclass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class Student extends Person {
private int studentNumber;
public Student() {
super();
studentNumber = 0;
}
public Student(String name, int number) {
super(name);
studentNumber = number;
}
public Student(String initialName) {
this(initialName, 0);
}
public int getStudentNumber() {
return studentNumber;
}
public void printAttributes() {
super.printAttributes();
System.out.println("Student Number : "
+ studentNumber);
//special();
}
}
|
Example Test Application
1
2
3
4
5
6
7
8
9
10
11
|
public class StudentApp {
public static void main(String[] args) {
Student noName = new Student();
Person ed = new Student("Ed", 10);
Student buford = new Student("Buford");
noName.printAttributes();
ed.printAttributes();
buford.printAttributes();
}
}
|
^ top
7.1.4: Adding Methods to Subclasses
- We added a member variable to our
Student subclass
public class Student extends Person {
private int studentNumber;
A Student has this attribute in addition to a name
name is inherited from Person
Also, we added a new instance method to the subclass:
public int getStudentNumber() {
return studentNumber;
}
A Student has this method in addition to all the methods of the superclass
Overriding Methods
- In addition to adding new members, we can change the way a works in a subclass
- Changing the way a method works in a subclass is known as overriding a method
- We overrode this method in our
Student subclass
public void printAttributes() {
System.out.println("Name: " + getName());
System.out.println("Student Number : "
+ studentNumber);
}
- Both superclass and subclass has a
printAttributes method
- Both methods have the same parameters (i.e. none)
- Thus, they have the same signature
- The method from the subclass overrides the superclass method
- Note that a subclass method will NOT override a superclass method if the parameters are different
- Would have different signatures
- Sometimes people confuse overriding with overloading
- See the table below for the similarities and differences
- Note that you can call an overridden method of the superclass from a subclass
- To do so, you use the keyword
super as shown here:
public void printAttributes() {
super.printAttributes();
System.out.println("Student Number : "
+ studentNumber);
}
Overriding Verses Overloading
| Overriding |
Overloading |
|
|
- Same signature
- One method in superclass, one in subclass
|
- Different signature
- Both methods can be in same class
|
^ top
7.1.5: Constructors and Inheritance
- Constructors are not inherited by a subclass
- Instead, superclass constructors are called by the subclass constructor
- Superclass constructors are called either implicitly or explicitly using
super()
Examples of Subclass Constructors
- Here is a no-parameter constructor for
Student:
public class Student extends Person {
private int studentNumber;
public Student() {
super();
studentNumber = 0;
}
...
The first statement of the constructor is super() which calls the constructor of the superclass
After the superclass constructor finishes, this constructor then initializes the attribute studentNumber to 0
We could have left out the call to super() because Java automatically includes it if not explicitly stated
If you want to call a different constructor, then you use super() with arguments of the correct type
...
public Student(String name, int number) {
super(name);
studentNumber = number;
}
This constructor passes the parameter name to the constructor of the superclass
After which the Student() constructor initializes the instance variable studentNumber
Note that super() must be first action in a constructor definition
More About Subclass Constructors
- Constructors cannot be overridden because they are not inherited
- However, as we have seen before, constructors can be overloaded within the same class
- Another capability of constructors is that they can call other constructors -- known as chaining
- To call another constructor, you use the construct
this()
- Like a call to
super(), Java will call the constructor (within the same class) that matches the types of arguments with the constructor parameters
- Here is an example using
this() and super() together
Example of this() and super() Constructor Call
- Class
Student has a constructor with two parameters:
String for the name attribute
int for the studentNumber attribute
public Student(String name, int number) {
super(name);
studentNumber = number;
}
Another constructor within Student takes just a String argument
Initializes the studentNumber attribute to a value of 0:
public Student(String initialName) {
this(initialName, 0);
}
Calls the constructor having two arguments within the same class
Note that you can call either this() or super() in a constructor, but not both
Whichever is used, it must be the first action taken by the constructor
Only one of them can be first, so if you want to invoke both:
- Use a call with
this() to call a constructor using super()
^ top
7.1.6: Using Access Modifiers
- You use the keywords
public, private and protected to control access to class members
- Controls access to class instance variables and methods
- Only a particular definition (unlike C++)
public Access: Interface Access
private Access: Don't Touch That!
protected Access: Inheritance Access
Package Access: the Default
^ top
7.1.7: Final Classes, Methods and Parameters
- The keyword
final is used in many ways
Final Classes
Final Methods
- Specifies that a method definition cannot be overridden with a new definition in a subclass
- For example:
private final void special() {
System.out.println("I am special");
}
Since you would never want the method to do anything else, it makes sense to make it final
Allows the compiler to generate more efficient code
Final Parameters
- Use final in a parameter list to prevent a method from assigning a new value
- For example:
public void doSomething(final int i, final int j) {
//...
}
This can prevent a bug where you might set new values to the parameter variables in error
The keyword final is not part of the method signature and does not affect how a method is overridden
^ top
7.1.8: Summary
^ top
Exercise 7.1
Take one minute to prepare an answer the following question:
- Given the following code, which one of the following constructors could be added to
MySub without causing a compile time error?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class MySuper {
int number;
MySuper(int i) {
number = i;
}
}
public class MySub extends MySuper {
int count;
MySub(int cnt, int num) {
super(num);
count = cnt;
}
// Add new constructor here
}
|
MySub() {}
MySub(int cnt) { super(); count = cnt; }
MySub(int cnt) { count = cnt; super(cnt); }
MySub(int cnt) { this(cnt, cnt); }
MySub(int cnt) { super(cnt); this(cnt, 0); }
^ top
7.2: Working With the Object Class
Objectives
At the end of the lesson the student will be able to:
- Use methods of the
Object class
- Override methods of the
Object superclass
- Write code to cast objects up and down inheritance chains
|
^ top
7.2.1: Methods of the Object Class
- Every class implicitly extends
java.lang.Object
- This makes the
Object class the ancestor of all Java classes
- Including all programmer-defined classes
- Thus, every class you write has access to the fields and methods of the
Object class
- That means you need to know how to work with the
Object class
- The following is a summary of some of the methods of the
Object class
- Method
clone() is complicated and I refer you to the textbook, chapters 8 and 13, for instructions
- Overriding
finalize() is usually unnecessary and should be avoided
- We already looked at overriding
toString(), which you should do for almost every class you write
- In the following sections we will look at how to make use of the other methods
Object Class Methods
| Method |
Description |
| clone() |
Returns a copy of this object as an Object object. You must implement the Cloneable interface to use this method. (Cover later) |
| equals(Object obj) |
Returns true if this object refers to the same space in memory as another object. Otherwise, returns false even if the other object contains the same data. |
| finalize() |
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. |
| getClass() |
Returns a Class object that represents the class of this object. |
| hashCode() |
Returns a hash code value for the object, which is supported for the benefit of hashtables. |
| toString() |
Returns a String object containing the class name followed by an @ symbol and the memory location (in hexadecimal) for the object. |
^ top
7.2.2: Determining an Object's Type
Using the instanceof Operator
- The
instanceof operator checks if a test object is in the inheritance hierarchy of a class type
- Syntax:
testObject instanceof ClassName
- Where:
- testObject: the object to test
- ClassName: the class to compare again
- For example:
Person ed = new Student("Ed", 10);
System.out.println(ed instanceof Student);
instanceof returns true if the testObject is a descendant of any ClassName
Using Reflection
System.out.println(info.getName());
More Information
^ top
7.2.3: Casting Objects
- Once you know what type of object you have, you may need to cast objects to their actual type
- This allows you to use the methods of the more specialized object
- Following is the inheritance chain for
Student

- Java will implicitly cast an object up the inheritance chain (upcasting)
- However, you must explicitly cast an object down the inheritance chain (downcasting)
Student ed = new Student("Ed", 1);
Object obj = ed; // cast Student to Object
Student ed2 = (Student) obj; // cast Object to Student
- Following shows how casting affects the methods you can call
Object obj = new Student("Ed", 1);
String studStr = obj.toString(); // OK
// String name = obj.getName(); // does not compile
Student ed = (Student) obj; // cast Object to Student
String name = ed.getName(); // OK
- Once we cast
obj to Student, we can use the getName() method
- Note that if you try to cast to an incompatible type you will get a compiler error
String str = (String) ed; // compiler error
^ top
7.2.4: Overriding the equals() Method
- To test if two objects refer to the same location, you use the
equals() method of the Object class
- For example:
1
2
3
4
5
6
7
8
9
10
|
public class EqualsTestApp {
public static void main(String[] args) {
Person p1 = new Person("Ed");
Person p2 = new Person("Ed");
if (p1.equals(p2))
System.out.println("true");
else
System.out.println("false");
}
}
|
public boolean equals(Object obj)
We want our Person to work if the passed reference is null:
if (obj == null) {
return false;
}
We also want our equals() to work for any kind of object reference
Thus, if the passed object is not the same kind, we return false
To test the exact type, we use the getClass() method:
if (getClass() != obj.getClass()) {
return false;
}
If our test object passes these cases, then we compare all the instance variables of our class for equality
To do this, we must first cast our object to the actual type and then make the comparisons
Person p = (Person) obj;
if (name.equals(p.getName())) {
return true;
}
return false;
Putting all this together we have:
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (getClass() != obj.getClass()) {
return false;
} else { // now safe to cast
Person p = (Person) obj;
if (name.equals(p.getName())) {
return true;
}
}
return false;
}
^ top
7.2.5: Overriding the hashCode() Method
- If you override
equals(), then you should override the hashCode() method as well.
- Otherwise, your code will not work correctly with the hash-based classes of the Java Collection like
HashTable
- A hashtable is like an array but allows non-integer indexes
- You will learn about hashtables later
- When an object is inserted in a hashtable, the
hashCode() method is called
- The value returned by
hashCode() determines where to insert the object in the table
- Producing an optimal hash code can be tricky, but we can produce a good approximation using the following recipe
- The recipe is from the book, Effective Java by Joshua Bloch pp. 36-41 (see more information below)
- Note that computing a hash code for a class may be more complex than shown below if the
equals() method is complex
- If you have a complex
equals() method you should read the chapter linked to in the More Information section below
Simple Hash Code Recipe
- Store a nonzero constant value like
42 in an int variable named result
int result = 17; // arbitrary nonzero value
- For every instance variable
x used in the comparison do the following:
- Compute an
int hash code named c for the instance variable using the following:
- If the type is a boolean, compute:
c = x ? 1 : 0
- If the type is
byte, char, short or int, compute: c = (int) x
- If the type is
long, compute: c = (int) (x ^ (x >>> 32))
- If the type is float, compute:
c = Float.floatToIntBits(x)
- If the type is double, compute:
long t = Double.doubleToLongBits(d); and then compute the hash code for a type long
- If the type is a class, compute:
c = (x == null) ? 0 : x.hashCode();
- If the type is an array, compute the hash code for every element of the array and combine the elements as shown in step 2b
- Combine the hash code c computed in step 2a as follows:
result = 31 * result + c;
Example Class Computing Hash Codes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
public class HashCodeRecipe {
private boolean b = true;
private char ch = 'X';
private long bow = 424242424242L;
private float f = 1.234F;
private double d = 1.234;
private String str = "Hi Mom!";
private int[] a = {90, 95, 87, 89, 98};
public int hashCode() {
final int ARBITRARY_NONZERO_VALUE = 17;
int result = ARBITRARY_NONZERO_VALUE;
int c = 0; // temporary hash code
c = b ? 1 : 0;
result = 31 * result + c;
c = (int) ch;
result = 31 * result + c;
c = (int) (bow ^ (bow >>> 32));
result = 31 * result + c;
c = Float.floatToIntBits(f);
result = 31 * result + c;
long t = Double.doubleToLongBits(d);
c = (int) (t ^ (t >>> 32));
result = 31 * result + c;
c = str.hashCode();
result = 31 * result + c;
for (int i : a) {
c = (int) i;
result = 31 * result + c;
}
return result;
}
public static void main(String[]args) {
HashCodeRecipe recipe = new HashCodeRecipe();
System.out.println(recipe.hashCode());
}
}
|
More Information
^ top
7.2.6: Summary
- Every class extends from
Object
- Thus you can use methods from
Object in your own classes
- You can cast an object up and down its inheritance chain
- Will not lose any data stored in the object
- You can determine the actual type of an
Object reference using either the:
instanceof operator
getClass() method
- You can override methods of the
Object class to improve the behavior of your class
Object method toString() is almost always overridden in subclasses
- Return a
String describing your object data
Object method equals() is overridden when you do not like the default behavior
- When you override equals(), you must override hashcode()
- Hash codes are tricky to optimize but we covered a "simple" recipe
^ top
Exercise 7.2
Take one minute to prepare an answer the following question:
- Given the following code, what will be printed?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class InstanceTester {
public static void main(String[] args) {
B b = new C();
A a = b;
if (a instanceof A) System.out.println("A");
if (a instanceof B) System.out.println("B");
if (a instanceof C) System.out.println("C");
if (a instanceof D) System.out.println("D");
}
}
class A {}
class B extends A {}
class C extends B {}
class D extends C {}
|
A will be printed
B will be printed
C will be printed
D will be printed
- The
Person class we covered previously has the following instance variable:
public class Person {
private String name;
// methods omitted
}
- Using the hash code recipe we discussed, what is an acceptable
hashCode() method for class Person?
Check answer
^ top
7.3: Midterm Review
Learner Outcomes
At the end of the lesson the student will be able to:
- Describe how to prepare for the midterm exam
- Describe how to take the midterm exam
|
^ top
7.3.1: About the Midterm Exam
Important Midterm Exam Information
Date and Time: 4/1/09 @ 3:30 P.M. to 4:50 P.M.
Location: Blackboard (Online)
|
- You must take the exam at the specified time or you will receive a score of zero (0)
- Except by prior arrangement with the instructor
- I am using Blackboard to administer the test
- Do not come to the classroom for the test
- Instead, find a computer with a fast Internet connection (such as the CTC)
- The exam is designed to take about one hour to complete
- However, you will have 75 minutes during the scheduled time to complete the exam
- You may have less time if you are late to the exam
- Since the exam is online, it is open book and open notes
- You are honor bound NOT to communicate with anyone but the instructor during the exam; thus:
- You may NOT call anyone but the instructor on a phone during the exam
- You may NOT use the Internet to email anyone but the instructor during the exam
- The instructor will be online and monitoring Blackboard during the exam
- Thus you may call or email the instructor during the exam about any questions or problems you have with the exam
- You will be able to view scores only after the instructor finishes grading
^ top
7.3.2: Recommended Preparation
- Try the Example Midterm in Blackboard
- These questions are intended to help you get a "feel" for taking an exam in Blackboard
- The questions are NOT intended to tell you everything that is on the exam
- Review your notes and prepare your 3" x 5" card
- Review your homework assignments and solutions
- You should be prepared to write short programs
^ top
7.3.3: Exam Taking Tips
- Save after every answer -- you can always choose another answer
- If you get stuck on a question, make your best guess and return later
- If you are equally uncertain between two choices, go with first impression
- You do not need to comment code for tests and exams
- Unless specifically instructed to in the exam question
- Use the full time available
- Check your work if you finish early
^ top
7.3.4: Questions and Answers
^ top
Wrap Up
Due Next: A6-Card Games (3/25/09)
Midterm Exam (4/1/09)
A7-Alien Polymorphism (4/8/09)
^ top
Home
| Blackboard
| Announcements
| Schedule
| Room Policies
| Course Info
Help
| FAQ's
| HowTo's
| Links
Last Updated: April 05 2009 @21:53:19
|