sd1042 introduction to software development. extending classes with inheritance robot dancingrobot...

96
SD1042 Introduction to Software Development

Upload: isabella-powell

Post on 17-Dec-2015

223 views

Category:

Documents


0 download

TRANSCRIPT

SD1042

Introduction to Software Development

Extending classes with inheritance

Robot DancingRobot

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

InterestAccount is a kind of

BankAccount

Employee

FullTimeEmployee PartTimeEmployee

FullTimeEmployee is a kind of Employee

PartTimeEmployee is a kind of Employee

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

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

Extending the Oblong class…

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 }}

The new-line character..

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

**************************************************

++++++++++++++++++++++++++++++++++++++++++++++++++

method overriding..

ClassA

ClassB

ClassA

ClassB

ClassA

ClassB

method overloading

ClassA

ClassB

ClassA

ClassB

method overriding

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;

}

}

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);

// 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

Abstract classes and methods…

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

Abstract classes and methods:

An example

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"; }}

Inheritance and Types …

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

The Object class….

Employee

PartTimeEmployee FullTimeEmployee

String BankAccount

Object

Generic Arrays

myList = new [100];Student[ ] Student

This array can just store Student objects.

myList = new [100];BankAccount[ ] BankAccount

This array can just store BankAccount objects.

myList = new [100];Object[ ] Object

This array can store any objects.

Adding items into a generic array..

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];

Retrieving items from a generic array..

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.

How do we tell the compiler that the second item in the array is of type BankAccount ?

Use the technique of type-casting!

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.

How could you use an array of Objects to store items of type int, double or a char?

Use a wrapper class!

Object

Integer

hidden int

Integer(int)

getValue():int

Character

hidden char

Character(char)

getValue():char

Double

hidden double

Double(double)

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 : 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; } }

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

}