Chapter 13 Chapter 13 - -
Inheritance Inheritance
Goals Goals
To learn about inheritance To learn about inheritance
To understand how to inherit and override To understand how to inherit and override superclass
superclassmethods methods
To be able to invoke superclassTo be able to invoke superclassconstructors constructors
To learn about protected and package access To learn about protected and package access control
control
To understand the common superclassTo understand the common superclassObject Object and to override its
and to override its toStringtoStringand equals methods and equals methods
In OOP languages, new classes can be derived In OOP languages, new classes can be derived from an existing class.
from an existing class.
Why?Why?
organizes related classesorganizes related classes
reduces code redundancyreduces code redundancy
increases code reuseincreases code reuse
enables polymorphic enables polymorphic referencesreferences
13.1 Introduction to Inheritance 13.1 Introduction to Inheritance
Inheritance: extend classes by adding methods Inheritance: extend classes by adding methods and fields
and fields
Example: Savings account is a bank account Example: Savings account is a bank account with interest
with interest
class
class SavingsAccountSavingsAccount extends extends BankAccountBankAccount {{
new methods new methods
new instance fields new instance fields } }
SavingsAccountSavingsAccountautomatically inherits all methods and automatically inherits all methods and instance fields of
instance fields of BankAccountBankAccount SavingsAccount
SavingsAccountcollegeFundcollegeFund = new SavingsAccount(10);= new SavingsAccount(10);
// Savings account with 10% interest // Savings account with 10% interest collegeFund.deposit(500);
collegeFund.deposit(500);
// OK to use
// OK to use BankAccountBankAccount method with method with SavingsAccountSavingsAccount // object
// object
Original/base class is known as the Original/base class is known as the superclasssuperclass (
(BankAccountBankAccount))
extending class is the extending class is the subclasssubclass((SavingsAccountSavingsAccount) )
Every class extends the Every class extends the Object
Objectclass either class either directly or indirectly directly or indirectly
Inheritance
Inheritance vs vs Interface Interface
Inheriting from class IS NOT the same as Inheriting from class IS NOT the same as implementing interface
implementing interface
subclass inherits behavior and statesubclass inherits behavior and state
Interfaces have no state or defined behavior Interfaces have no state or defined behavior (only names of shared methods)
(only names of shared methods)
Code Reuse Code Reuse
One advantage of inheritance is code reuse One advantage of inheritance is code reuse
Not “Not “reinventing the wheelreinventing the wheel””
Already have a class that does some base functions, Already have a class that does some base functions, why not just build up on it?
why not just build up on it?
Deposit, withdraw, getBalanceDeposit, withdraw, getBalancecommon among all common among all accounts
accounts
In subclass, specify added instance fields, added In subclass, specify added instance fields, added methods, and changed or overridden methods methods, and changed or overridden methods
Inheritance takes care of what is common, you define what Inheritance takes care of what is common, you define what is different
is different public class
public class SavingsAccountSavingsAccount extends extends BankAccountBankAccount{{ private double
private double interestRateinterestRate; ; public
public SavingsAccount(doubleSavingsAccount(double rate) {rate) { interestRate
interestRate = rate; = rate;
} }
public void
public void addInterestaddInterest() { () { double interest =
double interest = getBalancegetBalance() * () * interestRateinterestRate / / 100;
100;
deposit(interest deposit(interest); );
}} } }
Encapsulation Encapsulation
Why do we call getBalanceWhy do we call getBalance??
double interest =
double interest = getBalancegetBalance() * () * interestRate
interestRate / 100;/ 100;
Encapsulation: Encapsulation: addInterestaddInterest calls calls getBalancegetBalance because
because balancebalancefield of the field of the superclasssuperclassis is privateprivate
Cannot access private members of another class Cannot access private members of another class (even a subclass!)
(even a subclass!)
SavingsAccountSavingsAccountobject inherits the object inherits the balance balance
instance field from
instance field from BankAccountBankAccount, and gains one , and gains one additional instance field:
additional instance field: interestRateinterestRate
Note that Note that addInterestaddInterestcalls calls getBalancegetBalancewithout without specifying an implicit parameter (the calls apply specifying an implicit parameter (the calls apply to the same object)
to the same object)
Means the call to is Means the call to is getBalancegetBalance is applied to the is applied to the same object as the object that called
same object as the object that called addInterestaddInterest
Syntax Syntax
class
class SubclassNameSubclassName extends SuperclassNameextends SuperclassName { {
methods methods instance fields instance fields } }
13.2 Inheritance Hierarchies 13.2 Inheritance Hierarchies
Inheritance is a way to categorizeInheritance is a way to categorize
In real world, categories often use hierarchiesIn real world, categories often use hierarchies
Generic items yield more specific itemsGeneric items yield more specific items
Bird Bird Robin, Blue Jay, Cardinal, etc.Robin, Blue Jay, Cardinal, etc.
Sets of classes can form complex inheritance Sets of classes can form complex inheritance hierarchies
hierarchies
Hierarchy Hierarchy
What is the common set of features?What is the common set of features?
SuperclassSuperclass
There are all birds There are all birds class Bird{class Bird{……}}
ISA HierarchyISA Hierarchy
What is at the top of every hierarchy?What is at the top of every hierarchy?
Example Example
Consider a bank that offers its customers the Consider a bank that offers its customers the following account types:
following account types:
Checking account: no interest; small number of free Checking account: no interest; small number of free transactions per month, additional transactions are transactions per month, additional transactions are charged a small fee
charged a small fee
Savings account: earns interest that compounds Savings account: earns interest that compounds monthly
monthly
Inheritance Hierarchy
Inheritance Hierarchy Behaviors Behaviors
All bank accounts support the All bank accounts support the getBalancegetBalance
method method
All bank accounts support the All bank accounts support the depositdepositand and
withdraw
withdrawmethods, but the implementations methods, but the implementations differ
differ
Checking account needs a method Checking account needs a method deductFeesdeductFees; ; savings account needs a method
savings account needs a method addInterestaddInterest
13.3 Inheriting Instance Fields and 13.3 Inheriting Instance Fields and
Methods Methods
A subclass can define additional instance fields A subclass can define additional instance fields and methods
and methods
With existing methodsWith existing methods
They can overrideThey can overridedefinitions from the superclassdefinitions from the superclass
They can inherit them as isThey can inherit them as is
Overriding methods Overriding methods
Supply a different implementation of a method Supply a different implementation of a method that exists in the
that exists in the superclasssuperclass
Must have same signature (same name and same Must have same signature (same name and same parameter types)
parameter types)
If method is applied to an object of the subclass If method is applied to an object of the subclass type, the overriding method is executed
type, the overriding method is executed
Inherit method Inherit method
Don't supply a new implementation of a method Don't supply a new implementation of a method that exists in
that exists in superclasssuperclass
SuperclassSuperclassmethod can be applied to the method can be applied to the subclass objects
subclass objects
Add method Add method
Supply a new method that doesn't exist in the Supply a new method that doesn't exist in the superclass
superclass
New method can be applied only to subclass New method can be applied only to subclass objects
objects
Inheriting Instance Fields Inheriting Instance Fields
Can't override fields Can't override fields
Inherit field: All fields from the superclassInherit field: All fields from the superclassare are automatically inherited (but may not be visible) automatically inherited (but may not be visible)
Add field: Supply a new field that doesn't exist Add field: Supply a new field that doesn't exist in the
in the superclasssuperclass
Inheriting Methods Inheriting Methods
What if you define a new field with the same What if you define a new field with the same name as a
name as a superclasssuperclassfield? field?
Each object would have two instance fields of the Each object would have two instance fields of the same name
same name
Fields can hold different values Fields can hold different values
Legal but extremely undesirableLegal but extremely undesirable
Another instance of Another instance of shadowingshadowing
CheckingAccount
CheckingAccount Class Class
Overrides deposit and withdraw to increment the Overrides deposit and withdraw to increment the transaction count:
transaction count:
public class
public class CheckingAccountCheckingAccount extends extends BankAccountBankAccount {{ private
private intint transactionCount; // new instance field transactionCount; // new instance field
public void
public void deposit(doubledeposit(double amount) { . . . } amount) { . . . } public void
public void withdraw(doublewithdraw(double amount) { . . . } amount) { . . . } public void
public void deductFeesdeductFees() { . . . } // new method () { . . . } // new method }
}
EachEach CheckingAccountCheckingAccountobject has two instance object has two instance fields:
fields:
balance (balance (inherited frominherited from BankAccountBankAccount) )
transactionCounttransactionCount ((new tonew toCheckingAccountCheckingAccount))
You can apply four methods to You can apply four methods to CheckingAccount
CheckingAccountobjects: objects:
getBalancegetBalance() (() (inherited frominherited from BankAccountBankAccount) )
deposit(doubledeposit(double amount) amount) (overrides(overrides
BankAccount
BankAccount methodmethod) )
withdraw(doublewithdraw(double amount) (amount) (overridesoverrides
BankAccount
BankAccount method)method)
deductFeesdeductFees() () (new to(new toCheckingAccount)CheckingAccount)
Inheriting Private fields Inheriting Private fields
Consider deposit method of Consider deposit method of CheckingAccountCheckingAccount public void
public void deposit(doubledeposit(double amount)amount) {
{
transactionCount transactionCount++; ++;
// now add amount to balance // now add amount to balance
…
… } }
Inheriting Private fields Inheriting Private fields
Consider deposit method of Consider deposit method of CheckingAccountCheckingAccount public void
public void deposit(doubledeposit(double amount)amount) {
{
transactionCount transactionCount++; ++;
// now add amount to balance // now add amount to balance balance =
balance = balancebalance + amount;+ amount;
} }
Will this work?
Will this work?
Can't just add amount to balance Can't just add amount to balance
balancebalanceis a is a privateprivatefield of the field of the superclasssuperclass
A subclass has no access to private fields of its A subclass has no access to private fields of its superclass
superclass
Subclass must use public interface Subclass must use public interface
Inheriting Private fields Inheriting Private fields
Consider deposit method of Consider deposit method of CheckingAccountCheckingAccount public void
public void deposit(doubledeposit(double amount)amount) {
{
transactionCount transactionCount++; ++;
// now add amount to balance // now add amount to balance deposit(amount
deposit(amount););
} }
Will this work?
Will this work?
Invoking a
Invoking a Superclass Superclass Method Method
Can't just callCan't just call
deposit(amount deposit(amount))
in deposit method of
in deposit method of CheckingAccountCheckingAccount
That is the same asThat is the same as
this.deposit(amount
this.deposit(amount))//Checking account!//Checking account!
Calls the same method (infinite recursion)Calls the same method (infinite recursion)
Solution: super Solution: super
Java allows you to specify calling a method of Java allows you to specify calling a method of the super class with the keyword
the super class with the keyword supersuper
Invoke Invoke superclasssuperclassmethodmethod
super
super.deposit(amount.deposit(amount))
Now calls deposit method of Now calls deposit method of BankAccountBankAccountclass class
public void
public void deposit(doubledeposit(double amount)amount) {{
transactionCount transactionCount++; ++;
// Now add amount to balance // Now add amount to balance super.deposit(amount
super.deposit(amount); );
} }
public class
public class CheckingAccountCheckingAccount extends BankAccountextends BankAccount {
{
private static final
private static final intint FREE_TRANSACTIONS = 3; FREE_TRANSACTIONS = 3;
private static final double TRANSACTION_FEE = 2.0;
private static final double TRANSACTION_FEE = 2.0;
. . . . . . public void
public void withdraw(doublewithdraw(double amount)amount) {
{
transactionCount transactionCount++; ++;
// Now subtract amount from balance // Now subtract amount from balance super.withdraw(amount
super.withdraw(amount); );
} }
public void
public void deductFeesdeductFees()() {
{ if (
if (transactionCounttransactionCount > FREE_TRANSACTIONS)> FREE_TRANSACTIONS) {
{
double fees = TRANSACTION_FEE * double fees = TRANSACTION_FEE * (
(transactionCounttransactionCount -- FREE_TRANSACTIONS); FREE_TRANSACTIONS);
super.withdraw(fees super.withdraw(fees); );
} }
transactionCount transactionCount = 0; = 0;
} }
Object Class Object Class
a class a class extends Objectextends Objectby default when no by default when no extends
extendsclause is used, e.g:clause is used, e.g:
class Thing class Thing { ... } { ... }
class Thing extends Objectclass Thing extends Object { ... }
{ ... }
Override (redefine) Override (redefine)
We can
We can overrideoverridepublic (and protected) public (and protected) methods of any superclass methods of any superclass
Use the same
Use the same
signature signature
to override an to override an inherited method.inherited method.
13.4 Inheritance and Constructors 13.4 Inheritance and Constructors
Unlike members and methods of a superclass, Unlike members and methods of a superclass, constructors of a superclass are
constructors of a superclass are notnotinherited by inherited by its subclasses.
its subclasses.
You must define a constructor for a subclass or You must define a constructor for a subclass or use the default constructor added by the use the default constructor added by the compiler.
compiler.
How do you initialize superclassHow do you initialize superclassfields thoughfields though
In SavingsAccountIn SavingsAccount, how do we initialize balance?, how do we initialize balance?
13.4 Inheritance and Constructors 13.4 Inheritance and Constructors
super();
super();
Calls the default constructor of the Calls the default constructor of the superclasssuperclass
Analogous to this()Analogous to this()
Every constructor of a subclass must make a call to Every constructor of a subclass must make a call to the the superclasssuperclassconstructor.constructor.
If you don’If you don’t compiler will add int compiler will add in
A call to super( ) MUST be the first line of code in A call to super( ) MUST be the first line of code in the constructor
the constructor
Checking Account Checking Account
public class
public class CheckingAccountCheckingAccount extends extends BankAccountBankAccount {{
public
public CheckingAccount(doubleCheckingAccount(double initialBalanceinitialBalance) ) { {
// Construct
// Construct superclasssuperclass super(initialBalance super(initialBalance););
// Initialize transaction count // Initialize transaction count transactionCount
transactionCount = 0; = 0;
}} . . . . . .
} }
class
class MyClassMyClass {{ public
public MyClass(intMyClass(int x){x){
...
...
} } }} class
class SubClassSubClass extends extends MyClassMyClass{{ //No Constructor
//No Constructor }
}
WonWon’’t compile t compile ––default constructor of default constructor of SubClassSubClass tries to call super( ), but
tries to call super( ), but MyClassMyClass( ) is not ( ) is not defined
defined
class
class MyClassMyClass {{ public
public MyClass(intMyClass(int x){x){
...
...
}} }} class
class SubClassSubClass extends extends MyClassMyClass{{ public
public SubClassSubClass(){(){
super();//INVALID!
super();//INVALID!
}} }}
13.4 Inheritance and Constructors 13.4 Inheritance and Constructors
If a class has a superclass that is not the ObjectIf a class has a superclass that is not the Object class, then a constructor of the class should class, then a constructor of the class should make an explicit call to a constructor of the make an explicit call to a constructor of the superclass.
superclass.
Always provide a constructor for every class you Always provide a constructor for every class you define. Don
define. Don’’t rely on default constructors.t rely on default constructors.
class
class MyClassMyClass {{ public
public MyClass(intMyClass(int x){x){
......
}} }} class
class SubClassSubClass extends extends MyClassMyClass{{ public
public SubClass(intSubClass(inty){y){
super(y
super(y);//VALID!);//VALID!
} } } }
Ok to convert subclass reference to superclassOk to convert subclass reference to superclass reference (think:
reference (think: BlueJayBlueJayto Bird)to Bird)
SavingsAccount
SavingsAccount collegeFundcollegeFund = new = new SavingsAccount(10);
SavingsAccount(10);
BankAccount
BankAccount anAccountanAccount = = collegeFundcollegeFund;;
Object
Object anObjectanObject = = collegeFundcollegeFund; ;
SuperclassSuperclassreferences don't know the full story: references don't know the full story:
anAccount.deposit(1000); // OK anAccount.deposit(1000); // OK
anAccount.addInterest anAccount.addInterest(); ();
// No
// No----not a method of the class to whichnot a method of the class to which //
// anAccountanAccount belongsbelongs
Why is this?Why is this?
Conversions Conversions
Converting up to superclassConverting up to superclassleads to less leads to less information
information
Why would we want this?Why would we want this?
Reuse code that uses superclassReuse code that uses superclass
Reuse code that knows about the superclassReuse code that knows about the superclassbut not but not the subclass:
the subclass:
public void
public void transfer(doubletransfer(double amount, amount, BankAccountBankAccount other)
other) { {
withdraw(amount withdraw(amount););
other.deposit(amount other.deposit(amount); );
} }
Already learned how to use this method to Already learned how to use this method to transfer from one
transfer from one BankAccountBankAccountto anotherto another
But we can also use it to transfer from one But we can also use it to transfer from one CheckingAccount
CheckingAccountto another!to another!
The method doesn’The method doesn’t know the difference, because it t know the difference, because it only needs to know that a
only needs to know that a CheckingAccountCheckingAccountIS A IS A BankAccount
BankAccount
Super to Sub Conversion Super to Sub Conversion
How do we convert down the chainHow do we convert down the chain
BankAccountBankAccountobject object CheckingAccountCheckingAccount??
Is this safe?Is this safe?
We need a way to protect ourselves if we aren’We need a way to protect ourselves if we aren’t t sure
sure……
instanceof instanceof
Purpose: Check to see if an object is of a Purpose: Check to see if an object is of a particular class
particular class
Give: identifier and classGive: identifier and class
Returns: booleanReturns: boolean––true if it is that type, false true if it is that type, false otherwise
otherwise
Convert from super to sub Convert from super to sub
if (
if (anObjectanObject instanceofinstanceof BankAccountBankAccount)) {{
BankAccount
BankAccount anAccountanAccount = (= (BankAccountBankAccount) ) anObjectanObject;; . . .
. . . } }
13.6 Polymorphism 13.6 Polymorphism
In Ch.11, we learned that the type of the In Ch.11, we learned that the type of the identifier (Measurable) does not have to match identifier (Measurable) does not have to match the type of the object (
the type of the object (BankAccountBankAccount, Coin), Coin)
Inheritance demonstrates the same phenomenonInheritance demonstrates the same phenomenon
A BankAccountA BankAccountidentifier can be referring to a identifier can be referring to a BankAccount
BankAccount, , CheckingAccountCheckingAccount, or , or SavingsAccountSavingsAccount
Which version of deposit is called?Which version of deposit is called?
When is this determined?When is this determined?
BankAccount
BankAccount anAccountanAccount = new = new CheckingAccountCheckingAccount(); ();
anAccount.deposit(1000);
anAccount.deposit(1000);
Method calls are always determined on the Method calls are always determined on the type of the actual object being stored
type of the actual object being stored, not the , not the type of the reference/identifier
type of the reference/identifier
This ability to refer to multiple types with This ability to refer to multiple types with varying behavior is called
varying behavior is called polymorphismpolymorphism
Limitation Limitation
A limitation is that polymorphism only works if A limitation is that polymorphism only works if the reference type always has an implementation the reference type always has an implementation of that call
of that call
Ex. Will the following work?Ex. Will the following work?
Measurable x = new
Measurable x = new BankAccountBankAccount();();
x.deposit(500);
x.deposit(500);
Why? Why?
Previously, we called deposit on a BankAccountPreviously, we called deposit on a BankAccount object.
object.
When compiling, Java needs to know that a deposit When compiling, Java needs to know that a deposit method is legal to call on that object, not which method is legal to call on that object, not which method will be called
method will be called
Even though we didn’Even though we didn’t know which version would t know which version would be called, we can be guaranteed that any object be called, we can be guaranteed that any object stored with a
stored with a BankAccountBankAccountreference can handle reference can handle deposit
deposit
If the method is specific to only one subclass, If the method is specific to only one subclass, then the compiler can
then the compiler can’’t guarantee legalityt guarantee legality
Object
Object anObjectanObject = new = new BankAccountBankAccount();();
anObject.deposit(1000); // Compiling Error anObject.deposit(1000); // Compiling Error
--- ---
BankAccount
BankAccount baba = new = new CheckingAccountCheckingAccount();();
anObject.deductFees
anObject.deductFees(); // Compiling Error(); // Compiling Error
13.7 Access Control 13.7 Access Control
Java has four levels of controlling access to fields, Java has four levels of controlling access to fields,
methods, and classes:
methods, and classes:
publicpublicaccess access
Can be accessed by methods of all classesCan be accessed by methods of all classes
privateprivateaccess access
Can be accessed only by the methods of their own Can be accessed only by the methods of their own class
class
protectedprotectedaccess access
Can be accessed by methods of this class and Can be accessed by methods of this class and subclasses only
subclasses only
See Advanced Topic 13.3See Advanced Topic 13.3
packagepackageaccess access
The default, when no access modifier is given The default, when no access modifier is given
Can be accessed by all classes in the same package Can be accessed by all classes in the same package
13.8 Object: The Cosmic
13.8 Object: The Cosmic Superclass Superclass
Recall that everything inherits from Recall that everything inherits from ObjectObject
What comes in this class?What comes in this class?
Most useful methods: Most useful methods:
String String toStringtoString() ()
booleanboolean equals(Objectequals(Object otherObjectotherObject) )
Object clone()Object clone()
Why to these matter?Why to these matter?
Good idea to override these methods
package
package java.lang java.lang; ; class Object class Object
belongs to java.langbelongs to java.langpackagepackage
is the superclass of all other classesis the superclass of all other classes
has several generichas several genericmethodsmethods
equalsequals
toStringtoString
getClassgetClass
cloneclone
Object Class Methods Object Class Methods
booleanboolean equals ( Object equals ( Object objobj ))
returns true if (and only if) this object is alias of objreturns true if (and only if) this object is alias of obj
default: compares addressesdefault: compares addresses
String String toStringtoString ()()
returns a String representing this objectreturns a String representing this object
default: <class name>@<hashcodedefault: <class name>@<hashcode>>
13.8.1
13.8.1 toString toString() ()
Going to concentrate on the toStringGoing to concentrate on the toStringmethodmethod
Returns a string representation of the object Returns a string representation of the object
Useful for debugging: Useful for debugging:
Rectangle box = new Rectangle(5, 10, 20, 30);
Rectangle box = new Rectangle(5, 10, 20, 30);
String s =
String s = box.toStringbox.toString(); // Sets s to (); // Sets s to // "
// "java.awt.Rectangle[xjava.awt.Rectangle[x=5,y=10,width=20,height=30]" =5,y=10,width=20,height=30]"
Java insight Java insight
Unlike other methods, toStringUnlike other methods, toString() can actually be () can actually be called implicitly
called implicitly
ConcatenationConcatenation
"box = " + box;
"box = " + box;
Calling Calling print() print() or or println()println() System.out.println(box System.out.println(box););
How can the compiler know to do this?How can the compiler know to do this?
Because every object has a toStringBecause every object has a toStringmethod through method through Inheritance
Inheritance polymorphismpolymorphism
What does
What does toString toString return? return?
The Object class definition returns the object and a The Object class definition returns the object and a hashcode
hashcode(identifier)(identifier)
BankAccount
BankAccount momsSavingsmomsSavings = new BankAccount(5000); = new BankAccount(5000);
String s =
String s = momsSavings.toStringmomsSavings.toString();();
// Sets s to something like "BankAccount@d24606bf // Sets s to something like "BankAccount@d24606bf““
Pretty boringPretty boring……
Overriding
Overriding toString toString() ()
We can override the definition of any inherited We can override the definition of any inherited method!
method!
Usually want to know what’Usually want to know what’s inside the object s inside the object (fields, etc)
(fields, etc)
Print name of class, then the values of instance fields Print name of class, then the values of instance fields in brackets
in brackets
public String
public String toStringtoString()() {{
return "
return "BankAccount[balanceBankAccount[balance=" + balance + "]";=" + balance + "]";
} }
More useful version More useful version
Now this works better:Now this works better:
BankAccount
BankAccount momsSavingsmomsSavings= new BankAccount(5000);= new BankAccount(5000);
String s =
String s = momsSavings.toStringmomsSavings.toString(); ();
// Sets s to "
// Sets s to "BankAccount[balanceBankAccount[balance=5000]"=5000]"
Adv 13.4 Adv 13.4
toStringtoStringis a little harder with subclassesis a little harder with subclasses
How do we make How do we make BankAccountBankAccounttoStringtoStringwork for work for any subclasses?
any subclasses?
Use Use getClassgetClass() method() method public String
public String toStringtoString()() {{
return
return getClass().getNamegetClass().getName() + "[balance=" () + "[balance="
+ balance + "]";
+ balance + "]";
} }
equals equals
Seen before in the String classSeen before in the String class
Tests that the data in the two objects are the Tests that the data in the two objects are the same, not that both reference the same object same, not that both reference the same object
Version in Object does the same thing as ==Version in Object does the same thing as ==
Testing for equality might have different Testing for equality might have different meanings in different classes (do all the data meanings in different classes (do all the data members need to match, or just certain ones?) members need to match, or just certain ones?)
So we need to override!So we need to override!
public
public booleanboolean equals(Objectequals(Object obj)obj) {
{
BankAccount
BankAccount b = (b = (BankAccount)objBankAccount)obj;; return
return b.balanceb.balance == == this.balancethis.balance;; }
}
Parameter must be of type Object, but we must Parameter must be of type Object, but we must cast it before we can test the data members cast it before we can test the data members
It is pretty easy for BankAccountIt is pretty easy for BankAccount, with only 1 , with only 1 primitive data member, but gets trickier when primitive data member, but gets trickier when data members include arrays and other objects data members include arrays and other objects