Notes 03: Inheritance II

Download Report

Transcript Notes 03: Inheritance II

Inheritance
Part II
Lecture Objectives
• To learn about inheritance
• To understand how to inherit and override
superclass methods
• To be able to invoke superclass constructors
• To learn about protected and package
access control
• To understand the common superclass
Object and to override its toString() and
equals() methods
Implementing Remaining Methods
public class CheckingAccount extends BankAccount {
. . .
public void withdraw(double amount) {
transactionCount++;
// Now subtract amount from balance
super.withdraw(amount);
}
Implementing Remaining Methods (Cont’d)
public void deductFees()
{
private static final int FREE_TRANSACTIONS = 3;
private static final double TRANSACTION_FEE = 2.0;
if (transactionCount > FREE_TRANSACTIONS) {
double fees = TRANSACTION_FEE
* (transactionCount - FREE_TRANSACTIONS);
super.withdraw(fees);
}
transactionCount = 0;
}
. . .
}
Overriding vs. Overloading
• When you override a method, the new method definition in
the derived class has the same name and the same number
of types of parameters as the method definition in the base
class.
• When the name is the same, but the number or types of the
parameters differs, whether in the base class or in the
derived class, the method is overloaded in the derived
class.
Overriding vs. Overloading (Cont’d)
• Example:
public String getName(String title)
in the class SavingAccount and
public String getName()
in class BankAccount overloads the method getName()
since the two methods have different parameter lists.
 It should be noted that both methods [getName(String title)
and String getName()] are available in class SavingAccount!
A Subtle Point About Overloading
and Overriding
• Even when two methods have the same number of
parameters, a difference in parameter type is sufficient to
qualify for overloading.
• But, a reference to an ancestor class type can refer to a
descendant type.
• Hence an overridden method in an ancestor class
sometimes needs to be invoked explicitly using super.
The final Modifier
• You can prevent a method definition from being
overridden by adding the word final to the method
heading.
• Example:
public final void someMethod() {
…
}
• This is used rarely, but it produces more efficient code.
The final Modifier (Cont’d)
• An entire class can be declared final, in which case
it cannot be used as a superclass to derive another
class.
• Example:
package java.lang;
public final class Math {
…
}
• Therefore, the class Math can NOT be extended or
used as a superclass.
Private Instance Variables in the
Base Class
• Private instance variables inherited from a base class
cannot be accessed directly.
• Instead, they must be accessed using a method that is
not declared private.
• While this may seem inconvenient, it provides an
important mechanism for controlling access and
changes to instance variables in the base class.
Private Methods in the Base Class
• Like private instance variables, private method
inherited from a base class cannot be accessed
directly.
• Instead, they, too, must be accessed using a method
that is not declared private.
• This, too, provides an important mechanism for
controlling access to methods in the base class.
Common Error: Shadowing Instance
Fields
• A subclass has no access to the private
instance fields of the superclass
• Beginner's error: "solve" this problem by
adding another instance field with same name:
public class CheckingAccount extends BankAccount {
private double balance; // Don't
public void deposit(double amount) {
transactionCount++;
balance = balance + amount;
}
. . .
}
Common Error: Shadowing Instance
Fields (Cont’d)
• Now the deposit method compiles, but it
doesn't update the correct balance!
Figure 1: Shadowing Instance Fields
Subclass Construction
• super followed by a parenthesis indicates a
call to the superclass constructor
public class CheckingAccount extends BankAccount {
public CheckingAccount(double initialBalance) {
// Construct superclass
super(initialBalance);
// Initialize transaction count
transactionCount = 0;
}
. . .
}
Subclass Construction (Cont’d)
• Must be the first statement in subclass
constructor
• If subclass constructor doesn't call
superclass constructor, default superclass
constructor is used
 Default constructor: constructor with no parameters
 If all constructors of the superclass require
parameters, then the compiler reports an error
Syntax: Calling a Superclass
Constructor
ClassName(parameters){
super(parameters);
. . .
}
Example:
public CheckingAccount(double initialBalance) {
super(initialBalance);
transactionCount = 0;
}
Purpose:
To invoke a constructor of the superclass. Note that this statement must
be the first statement of the subclass constructor.
Converting Between Subclass
and Superclass Types
• It is OK to convert subclass reference to
superclass reference
SavingsAccount collegeFund = new SavingsAccount(10);
BankAccount anAccount = collegeFund;
Object anObject = collegeFund;
Converting Between Subclass
and Superclass Types (Cont’d)
• The three object references stored in
collegeFund, anAccount, and anObject all
refer to the same object of type SavingsAccount
Figure 2: Variables of Different Types Refer to the Same Object
Converting Between Subclass
and Superclass Types (Cont’d)
• Superclass references don't know the full
story:
anAccount.deposit(1000); // OK
anAccount.addInterest();
// No--not a method of the class to which anAccount belongs
• When you convert between a subclass object
to its superclass type:
 The value of the reference stays the same–it is the
memory location of the object
 But, less information is known about the object
Converting Between Subclass and
Superclass Types (Cont’d)
• Why would anyone want to know less about
an object?
 Reuse code that knows about the superclass but not
the subclass:
public void transfer(double amount, BankAccount other) {
withdraw(amount);
other.deposit(amount);
}
• Can be used to transfer money from any type
of BankAccount
Converting Between Subclass
and Superclass Types (Cont’d)
• Occasionally you need to convert from a
superclass reference to a subclass reference
BankAccount anAccount = (BankAccount) anObject;
• This cast is dangerous: if you are wrong, an
exception is thrown
Converting Between Subclass
and Superclass Types (Cont’d)
• Solution: use the instanceof operator
• instanceof: tests whether an object
belongs to a particular type
if (anObject instanceof BankAccount) {
BankAccount anAccount = (BankAccount) anObject;
. . .
}
Syntax: The InstanceOf Operator
object instanceof TypeName
Example:
if (anObject instanceof BankAccount) {
BankAccount anAccount = (BankAccount) anObject;
. . .
}
Purpose:
To return true if the object is an instance of TypeName (or one of its
subtypes), and false otherwise
The class Object: The Cosmic
Superclass
• All classes defined without an explicit extends
clause automatically extend Object
Figure 3: The Object Class is the Superclass of Every Java Class
The class Object: The Cosmic
Superclass (Cont’d)
•
Most useful methods:



•
String toString()
boolean equals(Object otherObject)
Object clone()
Good idea to override these methods in
your own classes
Overriding the tostring() Method
• Returns a string representation of the object
• Useful for debugging:
Rectangle box = new Rectangle(5, 10, 20, 30);
String s = box.toString();
// Sets s to "java.awt.Rectangle[x=5,y=10,width=20,height=30]"
Overriding the tostring() Method (Cont’d)
• The toString() method is called whenever
you concatenate a string with an object:
"box=" + box;
// Result: "box=java.awt.Rectangle[x=5,y=10,width=20,height=30]"
• The Object.toString() method prints class
name and the hash code of the object
BankAccount momsSavings = new BankAccount(5000);
String s = momsSavings.toString();
// Sets s to something like "BankAccount@d24606bf"
Overriding the tostring() Method (Cont’d)
• To provide a nicer representation of an
object, override the toString() method:
public String toString() {
return "BankAccount[balance=" + balance + "]";
}
• This works better:
BankAccount momsSavings = new BankAccount(5000);
String s = momsSavings.toString();
// Sets s to "BankAccount[balance=5000]"