Transcript Slide 1

SD1042
Introduction to Software
Development
Extending classes with inheritance
DancingRobot
Robot
Sharing
attributes
and
methods
Extending classes with inheritance
Learning objectives
•
explain the term inheritance;
•
design inheritance structures using UML notation;
•
implement inheritance relationships in Java;
•
distinguish between method overriding and method
overloading;
•
explain the term type cast and implement this in Java;
•
explain the use of the abstract modifier when applied to both
classes and methods;
•
describe the way in which all Java classes are derived from
the Object class.
Software Reuse
BankAccount
InterestAccount
is a kind of
BankAccount
InterestAccount
Employee
FullTimeEmployee
is a kind of
Employee
FullTimeEmployee
PartTimeEmployee
is a kind of
Employee
PartTimeEmployee
Representing inheritance in
UML diagrams..
Employee
number : String
name : String
Employee(String, String)
setName(String)
getNumber() : String
getName() : String
PartTimeEmployee
number : String
name : String
hourlyPay : double
PartTimeEmployee(String, String, double)
setName(String)
getNumber() : String
getName() : String
setHourlyPay(double)
getHourlyPay() :double
calculateWeeklyPay(int) :double
Employee
number : String
name : String
Employee(String, String)
setName(String)
getNumber() : String
getName() : String
PartTimeEmployee
number : String
name : String
hourlyPay : double
PartTimeEmployee(String, String, double)
setName(String)
getNumber() : String
getName() : String
setHourlyPay(double)
getHourlyPay() :double
calculateWeeklyPay(int) :double
Employee
number : String
name : String
Employee(String, String)
setName(String)
getNumber() : String
getName() : String
PartTimeEmployee
hourlyPay : double
PartTimeEmployee(String, String, double)
setHourlyPay(double)
getHourlyPay() :double
calculateWeeklyPay(int) :double
superclass
Employee
number : String
name : String
Employee(String, String)
setName(String)
getNumber() : String
getName() : String
subclass
base class
PartTimeEmployee
hourlyPay : double
PartTimeEmployee(String, String, double)
setHourlyPay(double)
UML notation
getHourlyPay() :double
for inheritance
calculateWeeklyPay(int) :double
derived class
Employee
number : String
name : String
Employee(String, String)
setName(String)
getNumber() : String
getName() : String
Code for the Employee class..
public class Employee
{
private String number;
private String name;
public Employee(String numberIn, String nameIn)
{
number = numberIn;
name = nameIn;
}
public void setName(String nameIn)
{
name = nameIn;
}
public String getNumber()
{
return number;
}
public String getName()
{
return name;
}
}
public class Employee
{
private String number;
private String name;
public Employee(String numberIn, String nameIn)
{
number = numberIn;
name = nameIn;
}
public void setName(String nameIn)
{
name = nameIn;
}
public String getNumber()
{
return number;
}
public String getName()
{
return name;
}
}
PartTimeEmployee
hourlyPay : double
PartTimeEmployee(String, String, double)
setHourlyPay(double)
getHourlyPay() :double
calculateWeeklyPay(int) :double
Code for the PartTimeEmployee
class..
public class PartTimeEmployee extends Employee
{
private double hourlyPay;
public PartTimeEmployee(String numberIn, String nameIn, double hourlyPayIn)
{
super( numberIn, nameIn );
Call to ‘super’
hourlyPay = hourlyPayIn;
must be first
}
instruction here
public double getHourlyPay()
{
return hourlyPay;
}
public void setHourlyPay(double hourlyPayIn)
{
hourlyPay = hourlyPayIn;
}
public double calculateWeeklyPay(int noOfHoursIn)
{
return noOfHoursIn * hourlyPay;
}
}
public class PartTimeEmployeeTester
{
public static void main(String[ ] args)
{
String number, name;
double pay;
int hours;
PartTimeEmployee emp;
System.out.print("Employee Number? ");
number = EasyScanner.nextString();
System.out.print("Employee's Name? ");
name = EasyScanner.nextString();
System.out.print("Hourly Pay? ");
pay = EasyScanner.nextDouble();
emp = new PartTimeEmployee(number, name, pay);
System.out.print("Hours worked this week? ");
hours = EasyScanner.nextInt();
System.out.println();
System.out.println(emp.getName());
System.out.println(emp.getNumber());
System.out.println(emp.calculateWeeklyPay(hours));
}
}
public class PartTimeEmployeeTester
{
public static void main(String[] args)
{
String number, name;
double pay;
int hours;
PartTimeEmployee emp;
System.out.print("Employee Number? ");
number = EasyScanner.nextString();
System.out.print("Employee's Name? ");
name = EasyScanner.nextString();
System.out.print("Hourly Pay? ");
pay = EasyScanner.nextDouble();
System.out.print("Hours worked this week? ");
hours = EasyScanner.nextInt();
emp = new PartTimeEmployee(number, name, pay);
System.out.println();
System.out.println(emp.getName());
System.out.println(emp.getNumber());
System.out.println(emp.calculateWeeklyPay(hours));
}
}
RUN
Employee Number? A103456
Employee's Name? Walter Wallcarpeting
Hourly Pay? 15.50
Hours worked this week? 20
Walter Wallcarpeting
A103456
310.0
RUN
Extending the Oblong class…
ExtendedOblong
Oblong
myOblong;myOblong;
myOblong == new
9.2);
new Oblong(6.5,
ExtendedOblong(6.5,
9.2,‘*’);
*********
*********
*********
*********
*********
*********
9.2
6.5
Oblong
length : double
height : double
Oblong(double, double)
setLength(double)
setHeight(double)
getLength() : double
getHeight() : double
calculateArea() : double
calculatePerimeter() : double
ExtendedOblong
symbol : char
ExtendedOblong(double, double, char)
setSymbol(char)
draw() : String
public class ExtendedOblong extends Oblong
{
private char symbol;
public ExtendedOblong (double lengthIn, double heightIn, char symbolIn)
{
super(lengthIn, heightIn);
symbol = symbolIn;
}
public void setSymbol(char symbolIn)
{
symbol = symbolIn;
}
public String draw()
{
// code to produce String goes here
}
}
The new-line character..
****
****
****
‘\n’LINE>
‘\n’LINE>
‘\n’LINE>
**** <NEW
****<NEW
**** <NEW
for (int i = 1; i <= height; i++)
{
for (int j = 1; j <= length; j++)
{
s = s + symbol;
}
s = s + '\n';
}
public String draw()
{
“ “;String();
String s ;= new
type casting
int length, height;
length = (int) getLength();
height = (int) getHeight(); What’s wrong here?
for (int i = 1; i <= height; i++)
{
for (int j = 1; j <= length; j++)
{
s = s + symbol;
}
s = s + '\n';
}
return s;
}
}
public
class ExtendedOblongTester
**********
{ **********
**********
public static
**********
{
**********
void main(String[] args)
ExtendedOblong extOblong = new ExtendedOblong(10,5,'*');
System.out.println(extOblong.draw());
}
++++++++++
extOblong.setSymbol('+');
++++++++++
System.out.println(extOblong.draw());
++++++++++
}
++++++++++
++++++++++
RUN
method overriding..
ClassA
ClassB
ClassA
ClassB
ClassA
method
overloading
ClassB
ClassA
ClassB
ClassA
method
overriding
ClassB
Customer
name : String
totalMoneyPaid : double
totalGoodsReceived : double
Customer (String, double)
Customer(String)
getName() : String
getTotalMoneyPaid() : double
getTotalGoodsReceived() : double
calculateBalance() : double
recordPayment(double)
dispatchGoods(double) : boolean
Customer
name : String
totalMoneyPaid : double
totalGoodsReceived : double
Customer (String, double)
Customer(String)
getName() : String
getTotalMoneyPaid() : double
getTotalGoodsReceived() : double
calculateBalance() : double
recordPayment(double)
dispatchGoods(double) : boolean
Method overloading
Customer
name : String
totalMoneyPaid : double
totalGoodsReceived : double
Customer(String)
getName() : String
getTotalMoneyPaid() : double
getTotalGoodsReceived() : double
calculateBalance() : double
recordPayment(double)
dispatchGoods(double) : boolean
GoldCustomer
creditLimit : double
GoldCustomer(String, double)
getCreditLimit() : double
setCreditLimit(double)
dispatchGoods(double) : boolean
Customer
name : String
totalMoneyPaid : double
totalGoodsReceived : double
Customer(String)
getName() : String
getTotalMoneyPaid() : double
getTotalGoodsReceived() : double
calculateBalance() : double
recordPayment(double)
dispatchGoods(double) : boolean
GoldCustomer
creditLimit : double
GoldCustomer(String, double)
getCreditLimit() : double
setCreditLimit(double)
dispatchGoods(double) : boolean
Customer
name : String
totalMoneyPaid : double
totalGoodsReceived : double
Customer(String)
getName() : String
getTotalMoneyPaid() : double
getTotalGoodsReceived() : double
calculateBalance() : double
recordPayment(double)
dispatchGoods(double) : boolean
GoldCustomer
creditLimit : double
GoldCustomer(String, double)
getCreditLimit() : double
setCreditLimit(double)
dispatchGoods(double) : boolean
method
overriding
Customer
name : String
totalMoneyPaid : double
totalGoodsReceived : double
Customer(String)
getName() : String
getTotalMoneyPaid() : double
getTotalGoodsReceived() : double
calculateBalance() : double
recordPayment(double)
dispatchGoods(double) : boolean
Code for the Customer class..
public class Customer
{
protected String name;
protected attributes are
similar to private
attributes except that
they are also visible to
subclasses.
}
public class Customer
{
protected String name;
protected double totalMoneyPaid;
protected double totalGoodsReceived;
public Customer(String nameIn)
{
name = nameIn;
totalMoneyPaid = 0;
totalGoodsReceived = 0;
}
}
public class Customer
{
protected String name;
protected double totalMoneyPaid;
protected double totalGoodsReceived;
public Customer(String nameIn)
{
name = nameIn;
totalMoneyPaid = 0;
totalGoodsReceived = 0;
}
// more methods go here
}
public boolean dispatchGoods(double goodsIn)
{
if(calculateBalance() >= goodsIn)
{
totalGoodsReceived = totalGoodsReceived + goodsIn;
return true;
}
else
{
return false;
}
}
GoldCustomer
creditLimit : double
GoldCustomer(String, double)
getCreditLimit() : double
setCreditLimit(double)
dispatchGoods(double) : boolean
Code for the GoldCustomer class..
public class GoldCustomer extends Customer
{
private double creditLimit;
public GoldCustomer(String nameIn, double limitIn)
{
name = nameIn;
totalMoneyPaid = 0;
totalGoodsReceived = 0;
creditLimit = limitIn;
}
}
public class GoldCustomer extends Customer
{
private double creditLimit;
public GoldCustomer(String nameIn, double limitIn)
{
super(nameIn);
creditLimit = limitIn;
}
public void setCreditLimit(double limitIn)
{
creditLimit = limitIn;
}
public double getCreditLimit()
{
return creditLimit;
}
// code for
}
dispatchGoods
public boolean dispatchGoods(double goodsIn)
{
if((calculateBalance() + creditLimit) >= goodsIn)
{
totalGoodsReceived = totalGoodsReceived + goodsIn;
return true;
}
else
{
return false;
}
}
Calling overridden methods..
Customer firstCustomer;
firstCustomer = new Customer("Jones");
GoldCustomer secondCustomer;
secondCustomer = new GoldCustomer("Cohen", 500);
// more code here
firstCustomer.dispatchGoods(98.76);
Customer firstCustomer;
firstCustomer = new Customer("Jones");
GoldCustomer secondCustomer;
secondCustomer = new GoldCustomer("Cohen", 500);
Will call
dispatchGoods
from the Customer
// more code here
class
firstCustomer.dispatchGoods(98.76);
Customer firstCustomer;
firstCustomer = new Customer("Jones");
GoldCustomer secondCustomer;
secondCustomer = new GoldCustomer("Cohen", 500);
// more code here
firstCustomer.dispatchGoods(98.76);
secondCustomer.dispatchGoods(32.44);
Customer firstCustomer;
firstCustomer = new Customer("Jones");
GoldCustomer secondCustomer;
secondCustomer = new GoldCustomer("Cohen", 500);
Will call
// more code here
dispatchGoods from
the GoldCustomer
class
firstCustomer.dispatchGoods(98.76);
secondCustomer.dispatchGoods(32.44);
Abstract classes
and methods…
abstract
Shape
Shape
abstract draw()
abstract methods
must be
overridden in
subclasses
We will never need
to create Shape
objects
Circle
Triangle
draw()
draw()
What if we definitely want to be able to draw
shapes like Circle and Triangle?
Abstract classes and methods:
An example
Employee
number : String
name : String
This
method
needs to be
declared
abstract
Employee(String, String)
setName(String)
getNumber() : String
getName() : String
getStatus() : String
FullTimeEmployee
This class
can be
declared
abstract
PartTimeEmployee
annualSalary : double
hourlyPay : double
FullTimeEmployee(String, String, double)
setAnnualSalary(double)
getAnnualSalary() : double
calculateMonthlyPay () : double
getStatus() : String
PartTimeEmployee(String,String, double)
setHourlyPay(double)
getHourlyPay() : double
calculateWeeklyPay(int) : double
getStatus() : String
public abstract class Employee
{
// attributes as before
// methods as before
abstract public String getStatus();
}
public class PartTimeEmployee extends Employee
{
// code as before
public String getStatus()
{
return "Part-Time";
}
}
public class FullTimeEmployee extends Employee
{
// code as before
public String getStatus()
{
return “Full-Time";
}
}
Inheritance and Types …
Shape
3DCircle
a kind
of Shape
CircleObject
is aiskind
of Shape
type
Circle
Circle c1 = new Circle ( );
Shape
3DCircle
Objectis a kind of Circle
type
3DCircle
Circle
Shape c3d = new 3DCircle ( );
3DCircle
Employee
abstract getStatus()
PartTimeEmployee
FullTimeEmployee
getStatus()
getStatus()
public class StatusTester
{
public static void tester(Employee employeeIn)
{
System.out.println(employeeIn.getStatus());
}
}
public class RunStatusTester
{
Full-Time
Part-Time
public static void main(String[ ] args)
{
FullTimeEmployee fte = new FullTimeEmployee("100", "Patel", 30000);
PartTimeEmployee pte = new PartTimeEmployee("101", "Jones", 12);
StatusTester.tester(fte);
StatusTester.tester(pte);
}
}
RUN
The Object class….
Object
String
Employee
BankAccount
PartTimeEmployee
FullTimeEmployee
Generic Arrays
Student[ ] myList = new Student [100];
This array can
just store
Student objects.
BankAccount[ ] myList = new BankAccount [100];
This array can just
store BankAccount
objects.
Object[ ] myList = new Object [100];
This array can
store any objects.
Adding items into a
generic array..
Object[ ] list = new Object [100];
Adding an Oblong object into the first position of array.
list [0] = new Oblong ( 8.2, 13.5);
Object[ ] list = new Object [100];
Adding a BankAccount object into the second
position of array.
list [1] = new BankAccount (“031”, “F Torres”);
Retrieving items from a
generic array..
Compiler regards all items in array as
type Object, not type BankAccount.
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
Withdrawing £250 from the BankAccount object.
list [1] .withdraw (250);
Something
This is a BankAccount
method wrong here
But we know the second item in the
array is actually of type BankAccount.
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
Withdrawing £250 from the BankAccount object.
list [1] .withdraw (250);
How do we tell the
compiler that the
second item in the
array is of type
BankAccount ?
Use the
technique of
type-casting!
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
Withdrawing £250 from the BankAccount object.
list [1] .withdraw (250);
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
Withdrawing £250 from the BankAccount object.
(BankAccount) list [1] .withdraw(250);
This is how we
type-cast.
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
Withdrawing £250 from the BankAccount object.
(BankAccount) list [1] .withdraw(250);
No we can use
BankAccount methods
How could you use
an array of Objects
to store items of
type int, double or
a char?
Use a wrapper
class!
Object
Integer
Character
Double
hidden int
hidden char
hidden double
Integer(int)
Character(char)
Double(double)
getValue():int
getValue():char
getValue():double
Wrapper classes
Autoboxing…
Object[] list = new Object[100];
list[0] = new Integer(37);
Java 5.0 allows us to make use of a technique
known as autoboxing:
list[0] = 37;
Unboxing…
Integer intObject = (Integer) list[0];
int x = intObject.getValue();
Java 5.0 allows us to make use of a technique
known as unboxing:
int x = (Integer) list[0];
Practical Work
Vehicle
regNo : String
make : String
year : int
value : double
Vehicle(String, String, int, double)
getRegNo() : String
getMake() : String
getYear() : int
getValue() : double
setValue(double)
calculateAge(int) : int
SecondHandVehicle
numberOfOwners : int
SecondHandVehicle(String, String, int, double, int)
getNumberOfOwners() : int
hasMultipleOwners() : boolean
Vehicle
regNo : String
make : String
year : int
value : double
Vehicle(String, String, int, double)
getRegNo() : String
getMake() : String
getYear() : int
getValue() : double
setValue(double)
calculateAge(int) : int
Lets implement
the highlighted
parts of the
Vehicle class.
Vehicle
regNo : String
make : String
year : int
value : double
Vehicle(String, String, int, double)
getRegNo() : String
getMake() : String
getYear() : int
getValue() : double
setValue(double)
calculateAge(int) : int
public class Vehicle
{
private String regNo;
private String make;
private int year;
private double value;
public Vehicle(String rIn, String mIn,
int yIn, double vIn)
{
regNo = rIn;
make = mIn;
year = yIn;
value = vIn;
}
}
Vehicle
SecondHandVehicle
numberOfOwners : int
SecondHandVehicle(String, String, int, double, int)
getNumberOfOwners() : int
hasMultipleOwners() : boolean
Lets implement the
highlighted parts of the
SecondHandVehicle
class.
Vehicle
SecondHandVehicle
numberOfOwners : int
SecondHandVehicle(String, String, int, double, int)
getNumberOfOwners() : int
hasMultipleOwners() : boolean
public class SecondHandVehicle extends Vehicle
{
private int numberOfOwners;
public SecondHandVehicle(String rIn, String mIn, int yIn, double vIn, int nIn)
{
super (rIn, mIn, yIn, vIn);
numberOfOwners = nIn;
}
}
Once you have
completed these
classes
remember to
create a third
tester class.
This class should
generate a
SecondHandVehicle
object and then call
its methods.
public class TesterProgram
{
public static void main (String[ ] args)
{
// generate at least 1 SecondHandVehicle object
// test the object by calling its methods
}