sd1042 introduction to software development. extending classes with inheritance robot dancingrobot...
TRANSCRIPT
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.
Employee
FullTimeEmployee PartTimeEmployee
FullTimeEmployee is a kind of Employee
PartTimeEmployee is a kind of Employee
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
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
subclass
base class
derived class
UML notation for inheritance
Code for the Employee class..
Employee
number : String name : String
Employee(String, String) setName(String) getNumber() : String getName() : String
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; }}
Code for the PartTimeEmployee class..
PartTimeEmployee hourlyPay : double
PartTimeEmployee(String, String, double) setHourlyPay(double) getHourlyPay() :double calculateWeeklyPay(int) :double
public class PartTimeEmployee extends Employee { private double hourlyPay; public PartTimeEmployee(String numberIn, String nameIn, double hourlyPayIn) { hourlyPay = hourlyPayIn; } public double getHourlyPay() { return hourlyPay; } public void setHourlyPay(double hourlyPayIn) { hourlyPay = hourlyPayIn; } public double calculateWeeklyPay(int noOfHoursIn) { return noOfHoursIn * hourlyPay; }}
super( );numberIn, nameInCall to ‘super’ must be first instruction here
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
RUN
Employee Number?
Walter WallcarpetingA103456310.0
Employee's Name? Hourly Pay? Hours worked this week?
A103456Walter Wallcarpeting
15.5020
6.5
9.2
Oblong myOblong;
myOblong
******************************************************
ExtendedOblong myOblong;
= new ExtendedOblong(6.5, 9.2,‘*’);= new Oblong(6.5, 9.2);
ExtendedOblong
symbol : char
ExtendedOblong(double, double, char) setSymbol(char) draw() : String
Oblong
length : doubleheight : double
Oblong(double, double)setLength(double)setHeight(double)getLength() : doublegetHeight() : doublecalculateArea() : doublecalculatePerimeter() : double
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 }}
for (int i = 1; i <= height; i++){ }
************
**** **** ****<NEW LINE> <NEW LINE>‘\n’ ‘\n’
for (int j = 1; j <= length; j++){ s = s + symbol; }s = s + '\n';
<NEW LINE>‘\n’
public String draw(){ String s ; int length, height; length = getLength(); height = getHeight(); for (int i = 1; i <= height; i++) { for (int j = 1; j <= length; j++) { s = s + symbol; } s = s + '\n'; } return s; }}
= “ “;= new String();
(int)(int)
type casting
What’s wrong here?
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
**************************************************
++++++++++++++++++++++++++++++++++++++++++++++++++
Customer
name : StringtotalMoneyPaid : doubletotalGoodsReceived : doubleCustomer (String, double)Customer(String)getName() : StringgetTotalMoneyPaid() : doublegetTotalGoodsReceived() : doublecalculateBalance() : doublerecordPayment(double)dispatchGoods(double) : boolean
Customer
name : StringtotalMoneyPaid : doubletotalGoodsReceived : doubleCustomer (String, double)Customer(String)getName() : StringgetTotalMoneyPaid() : doublegetTotalGoodsReceived() : doublecalculateBalance() : doublerecordPayment(double)dispatchGoods(double) : boolean
Method overloading
Customer
name : StringtotalMoneyPaid : doubletotalGoodsReceived : double
Customer(String)getName() : StringgetTotalMoneyPaid() : doublegetTotalGoodsReceived() : doublecalculateBalance() : doublerecordPayment(double)dispatchGoods(double) : boolean
GoldCustomer
creditLimit : double
GoldCustomer(String, double)getCreditLimit() : doublesetCreditLimit(double)dispatchGoods(double) : boolean
Customer
name : StringtotalMoneyPaid : doubletotalGoodsReceived : double
Customer(String)getName() : StringgetTotalMoneyPaid() : doublegetTotalGoodsReceived() : doublecalculateBalance() : doublerecordPayment(double)dispatchGoods(double) : boolean
GoldCustomer
creditLimit : double
GoldCustomer(String, double)getCreditLimit() : doublesetCreditLimit(double)dispatchGoods(double) : boolean
Customer
name : StringtotalMoneyPaid : doubletotalGoodsReceived : double
Customer(String)getName() : StringgetTotalMoneyPaid() : doublegetTotalGoodsReceived() : doublecalculateBalance() : doublerecordPayment(double)dispatchGoods(double) : boolean
GoldCustomer
creditLimit : double
GoldCustomer(String, double)getCreditLimit() : doublesetCreditLimit(double)dispatchGoods(double) : boolean
method overriding
Customer
name : StringtotalMoneyPaid : doubletotalGoodsReceived : double
Customer(String)getName() : StringgetTotalMoneyPaid() : doublegetTotalGoodsReceived() : doublecalculateBalance() : doublerecordPayment(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;
}
}
Code for the GoldCustomer class..
GoldCustomer
creditLimit : double
GoldCustomer(String, double)getCreditLimit() : doublesetCreditLimit(double)dispatchGoods(double) : boolean
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;
}
}
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);
// more code here
firstCustomer.dispatchGoods(98.76);
Will call dispatchGoods from the Customer class
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);
// more code here
firstCustomer.dispatchGoods(98.76);
secondCustomer.dispatchGoods(32.44);
Will call dispatchGoods from the GoldCustomer class
draw()
abstract draw()
draw()
Shape
Circle Triangle
abstract Shape
We will never need to create Shape objects
What if we definitely want to be able to draw shapes like Circle and Triangle?
abstract methods must be overridden in subclasses
Employee
number : String name : String
Employee(String, String) setName(String) getNumber() : String getName() : String getStatus() : String
FullTimeEmployee
annualSalary : double
FullTimeEmployee(String, String, double) setAnnualSalary(double) getAnnualSalary() : double calculateMonthlyPay () : double getStatus() : String
PartTimeEmployee
hourlyPay : double
PartTimeEmployee(String,String, double) setHourlyPay(double) getHourlyPay() : double calculateWeeklyPay(int) : double getStatus() : String
This class can be declared abstractThis
method needs to be declared abstract
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"; }}
Shape
Circle
3DCircle
Circle is a kind of Shape
3DCircle is a kind of Circle
3DCircle is a kind of Shape
c1 = new Circle ( );
c3d = new 3DCircle ( );
CircleShape
3DCircleShape
Object type
Circle
Object type
getStatus()
abstract getStatus()
getStatus()
Employee
PartTimeEmployee FullTimeEmployee
public class StatusTester{ public static void tester(Employee employeeIn) { System.out.println(employeeIn.getStatus()); }}
public class RunStatusTester
{
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
Full-TimePart-Time
list [0] = new Oblong ( 8.2, 13.5);
Adding an Oblong object into the first position of array.
Object[ ] list = new Object [100];
list [1] = new BankAccount (“031”, “F Torres”);
Adding a BankAccount object into the second position of array.
Object[ ] list = new Object [100];
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
Withdrawing £250 from the BankAccount object.
list [1]
Something wrong here
Compiler regards all items in array as type Object, not type BankAccount.
This is a BankAccount method
.withdraw (250);
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
list [1]
But we know the second item in the array is actually of type BankAccount.
.withdraw (250);
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
Object[ ] list = new Object [100];
list [1] = new BankAccount(“031, “F Torres”);
Withdrawing £250 from the BankAccount object.
Object
Integer
hidden int
Integer(int)
getValue():int
Character
hidden char
Character(char)
getValue():char
Double
hidden double
Double(double)
getValue():double
Wrapper classes
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;
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];
Vehicle
regNo : Stringmake : Stringyear : intvalue : double
Vehicle(String, String, int, double)getRegNo() : StringgetMake() : StringgetYear() : intgetValue() : doublesetValue(double)calculateAge(int) : int
SecondHandVehicle
numberOfOwners : int
SecondHandVehicle(String, String, int, double, int)getNumberOfOwners() : inthasMultipleOwners() : boolean
Vehicle
regNo : Stringmake : Stringyear : intvalue : double
Vehicle(String, String, int, double)getRegNo() : StringgetMake() : StringgetYear() : intgetValue() : doublesetValue(double)calculateAge(int) : int
Lets implement the highlighted parts of the Vehicle class.
Vehicle
regNo : Stringmake : Stringyear : intvalue : double
Vehicle(String, String, int, double)getRegNo() : StringgetMake() : StringgetYear() : intgetValue() : doublesetValue(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;
} }
Lets implement the highlighted parts of the SecondHandVehicle class.
SecondHandVehicle
numberOfOwners : int
SecondHandVehicle(String, String, int, double, int)getNumberOfOwners() : inthasMultipleOwners() : boolean
Vehicle
SecondHandVehicle
numberOfOwners : int
SecondHandVehicle(String, String, int, double, int)getNumberOfOwners() : inthasMultipleOwners() : boolean
Vehicle
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; } }