What We Will Cover
Illuminations
Questions on Completed Assignments?
Questions from last class?
^ top
6.1: Inheritance
Objectives
At the end of the lesson the student will be able to:
- Use inheritance in Java programs
- Chain constructors from subclasses to superclasses
- Override methods
- Assign, pass and cast references
- Choose between composition and inheritance
|
^ top
6.1.1: Introducing Inheritance
Inheritance: ability to define new classes from existing ones.
About Inheritance
- Can define a general class and then later define more specialized classes by adding new capabilities
- General class is called the superclass (base, parent)
- More specialized class called the subclass (derived, child)
- Classes higher in the hierarchy called ancestor classes
- Classes lower in the hierarchy called descendent classes
- After developing a general class, only need to write the "specialized" code for each subclass
- Subclasses inherit all the properties of the general class
- Add or modify instance variables and methods
For Example
Car inherits from Vehicle
Vehicle has several parts that are inherited by Car
- Derived class
Car could set the number of wheels (e.g. 4) and make other adjustments
Extending Java
- Deriving a new class from an existing one requires the
extends clause
- Subclass can only extend one superclass
- Java does not support multiple inheritance
- Interfaces (discussed later) achieve much of the same effect
^ top
6.1.2: Class Hierarchies
- Classes can be derived from derived classes
- Subclass objects can be treated as superclass objects
- Child classes can be parent classes
- Reverse is not true
- Circle is a Shape, but Shape is not always a Circle
- Every class implicitly extends
java.lang.Object
- Unless otherwise extended in the class definition’s first line
Example of Class Hierarchy
- The base class can be used to implement specialized classes
- For example: Person, Employee, Faculty, and Staff
- Classes can be derived from the classes derived from the base class, etc.
- Example implementation of the superclass shown below
Example Superclass
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(String newName) {
name = newName;
}
public void printAttributes() {
System.out.println("Name: " + name);
}
public boolean sameName(Person otherPerson) {
return (this.name.equalsIgnoreCase(
otherPerson.name));
}
private void specialMethod() {
System.out.println("I am special");
}
}
All people have names, so main attribute is the String name
Default constructor sets name to a default value
Has accessor methods to get and set the name
One other class method: sameName
Compares the values of the name attributes for objects of the class
Note that the methods are public and the name attribute is private
^ top
6.1.3: Constructors and Inheritance
Superclass Constructor
- Initializes superclass instance variables of subclass
- Constructors not inherited by subclass
- Instead, superclass constructors are called by the subclass
- Called either implicitly or explicitly from a subclass using
super
Examples of Subclass Constructors
- Keyword
extends in first line
- Defines a subclass based on the superclass
public class Student extends Person {
private int studentNumber;
public Student() {
super();
studentNumber = 0;
}
...
Default constructor initializes attribute studentNumber to 0
super() calls the parent's default constructor
Included automatically by Java if not explicitly stated
super() must be first action in a constructor definition
...
public Student(String newName, int newStudentNumber) {
super(newName);
studentNumber = newStudentNumber;
}
Overloaded constructor passes parameter newName to constructor of superclass
Also initializes the instance variable that is not in the superclass
More About Subclass Constructors
- Constructors cannot be overridden
- Constructors can be overloaded, but only in the same class
- Constructors can call other constructors -- known as chaining
- Use
super() to invoke a constructor in the superclass
- Use
this() to invoke a constructor within the same class
- Whichever is used 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 with super()
Example of this() and super() Constructor Call
- Student class has a constructor with two parameters:
String for the name attribute
int for the studentNumber attribute
public Student(String newName, int newStudentNumber) {
super(newName);
studentNumber = newStudentNumber;
}
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
^ top
6.1.4: Overriding Methods
- Following is an example of adding an attribute in a subclass
private int studentNumber;
Note that an attribute for the student number has been added
Student has this attribute in addition to name, which is inherited from Person
Following is an example of overriding a method in a 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
Method from the subclass overrides (replaces) the superclass method
Will not override the superclass if the parameters are different
- Would have different signatures
Called overriding -- not to be confused with overloading
Can call to an overridden method, instead, using super
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
|
The final Modifier
- Specifies that a method definition cannot be overridden with a new definition in a subclass
- For example:
public final void specialMethod() {
...
Used in specification of some methods in standard libraries
Allows the compiler to generate more efficient code
Can also declare an entire class to be final
Means it cannot be extended to a subclass
Access Modifiers and Inheritance
private instance variables from the parent class are not available by name in derived classes
- Use accessor methods to change them
private methods are not inherited either
- Use
public or protected to allow methods or variables to be inherited
- Only helper methods should be declared private
^ top
6.1.5: Using References
- What is the "Type" of a subclass?
- Subclasses have more than one type
- Have the type of the subclass they define
- Also have the type of every superclass
- All the way to the top of the class hierarchy
- All classes derive from the original, predefined class
Object
Object is called the "Eve" class since it is the original class for all other classes
Assignment Compatibility
- Four possible ways to mix and match references
- Not all of them work or make sense
- Refer to superclass object with superclass reference
- Refer to subclass object with subclass reference
- Refer to subclass object with superclass reference
- Can refer only to superclass members
- Refer to superclass object with subclass reference
For example:
- Assume that
Employee is a subclass of Person
- Can assign an object of a subclass to a variable of any superclass type
Person josephine;
Student good = new Student();
josephine = good;
Can not assign an object of an superclass to a variable of a subclass type
Person josephine = new Person();
Student good;
good = josephine; //Not allowed
Using instanceof
- Can ask Java to test the type of a subclass using
instanceof operator
- For example:
System.out.println(ed instanceof Student);
The Compleat Student
public class Student extends Person {
private int studentNumber;
public Student() {
super();
studentNumber = 0;
}
public Student(String newName, int newStudentNumber) {
super(newName);
studentNumber = newStudentNumber;
}
public Student(String initialName) {
this(initialName, 0);
}
public void printAttributes() {
super.printAttributes();
System.out.println("Student Number : "
+ studentNumber);
//specialMethod();
}
public static void main(String[] a) {
Student noName = new Student();
Person ed = new Student("Ed", 10);
Student buford = new Student("Buford");
noName.printAttributes();
ed.printAttributes();
buford.printAttributes();
System.out.println(ed instanceof Student);
}
}
^ top
6.1.6: Composition vs. Inheritance
Inheritance
- Create a class (subclass) from an existing one (superclass)
- Subclass creation does not affect superclass
- New class inherits attributes and behaviors
- Form of software reuse
- "Is a" relationship: e.g.
Employee is a Person
Composition
- "Has a" relationship: e.g.
Employee has a TelephoneNumber
Choosing Between Inheritance and Composition
- Only use inheritance for permanent "is-a" relationships
- For example:
- Given the class
Employee, should manager and cashier use inheritance?
- Not if the roles might change over the life of the program
- Would require creating new objects when changed
- Easier to just assign the role to a variable
^ top
Exercise 6.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?
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(); count = cnt; }
MySub(int cnt) { super(cnt); this(cnt, 0); }
^ top
6.2: Abstract Classes and Interfaces
Objectives
At the end of the lesson the student will be able to:
- Use abstract classes
- Use interfaces
|
^ top
6.2.1: About Abstract Classes
- Any class can be specified with the keyword
abstract
- Indicates that objects cannot be instantiated
- Used when classes are too generic to define real objects
- For example:
TwoDimensionalShape
- Provides superclass from which other classes may inherit
- Normally referred to as an abstract superclass
- Must declare a class abstract if it contains an abstract method
Abstract Methods
- Method declaration without a method body
void draw();
^ top
6.2.2: About Interfaces
Interface: a named collection of method definitions without implementations, as well as constants.
- An even more abstract "class" is an interface
- Can sometimes replace the use of an abstract class
- However, interfaces have even more restrictions than abstract classes
- Cannot implement any methods, unlike an abstract class
- Provides added flexibility in inheritance hierarchies
- Any class can have only one superclass
- But any class can implement as many interfaces as desired
^ top
6.2.3: Defining Interfaces
<interface header> {
<interface body>
}
Definition of an interface begins with interface keyword
Followed by the name of the interface
Interface body usually contains public abstract methods
Classes that implement the interface must implement these methods
For example:
interface Drawable {
void draw();
}
Implements an abstract method draw()
No implementation of the method can be given
Implementation is up to the implementing class
Note that interface methods cannot be declared static
Any interface method that is implemented becomes an instance method
^ top
6.2.4: Implementing Interfaces
- Any class can choose to implement zero or more interfaces
- Classes implementing an interface add the keyword
implements in the class header
- Follow
implements keyword with a comma-delimited list of interface names
- For example:
public class Shape implements Drawable
Class Shape must now implement the method draw()
^ top
6.2.5: Constants
- Interfaces can also define constants
- Such constants are implicitly
public, static and final
- These interfaces can be accessed by any class
- For example:
public interface Constants {
double PI = Math.PI;
}
Any class can now access the constant PI
double x = Constants.PI * 2;
^ top
6.2.6: Extending Interfaces
- Interfaces can extend other interfaces using the
extends clause
- Interfaces can extend more than one interface
- For example:
interface Drawable2 extends Drawable, Constants {
}
Interface Drawable2 has the method from Drawable and the constant from Constants
^ top
6.2.7: Supertypes
- Interfaces define new types
- Variables can be defined using the interface type
- References to classes implementing the interface can be stored in the variable
- Interfaces the a class implements and the classes it extends are called supertypes
- Will explore the polymorphic behavior of interfaces in the next section
^ top
Exercise 6.2
Take one minute to prepare an answer the following question:
- Which of the following statements are true about interfaces
- Members of an interface are never static
- Members of an interface can always be defined static
- Interfaces can implement variables but not methods
- Interfaces can extend any number of other interfaces
- Constants in an interface must be declared public or compilation will fail
^ top
6.3: Polymorphism
Objectives
At the end of the lesson the student will be able to:
- Use polymorphism in Java programs
|
^ top
6.3.1: About Polymorphism
Polymorphism: ability to use generic messages (method calls) to produce different results based on the object that receives the message.
- Polymorphism is about making systems extensible
- Programs are written to use superclass methods
- Methods are overridden in subclasses
- Objects of appropriate types are created
- Objects use the appropriate method through a process known as dynamic binding
- Advantage of polymorphism:
- Encourages object decoupling by reducing dependencies
- Classes are easily added to the system
- Easier to extend the system
^ top
6.3.2: Type Fields and switch Statements
- One approach to objects knowing how to act for their types is using
switch statements
- Determine appropriate action for object using a
switch statement based on object’s type
- Known as "big-switch" programming
- Error prone when adding and deleting switch statements
- Programmer can forget to make appropriate type test
- More elegant solution is to use dynamic binding
- Polymorphic programming can eliminate need for switch logic
^ top
6.3.3: Static vs. Dynamic Binding
Binding: determining which method to call based on its signature.
- Static binding: done at compile time
- Dynamic binding: done at run time
- Compilation binds memory locations to methods before running a program
- Thus, binding done at compile time is called static, or early, binding
- Binding done at run time is called dynamic, or late, binding
^ top
6.3.4: Polymorphism Example
- Let's define a set of shape objects that know how to "draw" themselves
- Use the
Drawable interface to define expected behavior
- Implementation of method
draw() overridden in every subclass of Shape
interface Drawable {
void draw();
}
class Shape implements Drawable {
public void draw() {
System.out.println("Drawing a Shape.");
}
}
class Circle extends Shape {
public void draw() {
System.out.println("Drawing a Circle.");
}
}
class Rectangle extends Shape {
public void draw() {
System.out.println("Drawing a Rectangle.");
}
}
class Square extends Rectangle {
public void draw() {
System.out.println("Drawing a Square.");
}
}
class Map implements Drawable {
public void draw() {
System.out.println("Drawing a Map.");
}
}
public class Polymorph {
public static void main(String args[]) {
Shape[] shapes = {new Circle(),
new Rectangle(), new Square()}; //(1)
Drawable[] drawables = {new Shape(),
new Rectangle(), new Map()}; //(2)
System.out.println("Draw shapes:");
for (int i = 0; i < shapes.length; i++) //(3)
shapes[i].draw();
System.out.println("Draw drawables:");
for (int i = 0; i < drawables.length; i++)//(4)
drawables[i].draw();
}
}
At (1), shapes[] holds references to various Shape objects
At (2), drawables[] holds references to classes that implement Drawable interface
Calling the draw() method at (3) and (4) relies on polymorphism
At runtime, dynamic lookup determines which draw() method to use
Easy to add new classes to the Shape or Drawable system
No need to change any conditional logic
^ top
Exercise 6.3
Take two minutes to prepare an answer the following questions.
- What is the class hierarchy of the
Polymorph example above?
- What will be the result of attempting to compile and run the following class?
public class Polymorphism {
public static void main(String args[]) {
A ref1 = new C();
B ref2 = (B) ref1;
System.out.println(ref2.f());
}
}
class A { int f() { return 1; } }
class B extends A {
int f() { return 2; }
}
class C extends B {
int f() { return 3; }
}
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Schedule
| Expectations
| Syllabus
Help
| FAQ's
| HowTo's
| Links
Last Updated: October 08 2003 @17:08:40
|