Software Engineering I SENG201
Lecture 10 – Interface classes March 14, 2022
Copyright By PowCoder代写 加微信 powcoder
Lecture pace
• Response rate: 31%
*Assuming those who did not respond are OK (“About right”)
Previous lecture
1. Introduction to arrays
2. Multi-dimensional arrays
3. Utilities for arrays
4. Array lists
1. Introduction to interface classes in Java
2. Interfaces in UML
3. Interesting features of interfaces
1. Introduction to interface classes in Java
2. Interfaces in UML
3. Interesting features of interfaces
Motivating example
public class DataSet // computes information for a set of bank accounts
// only stores number of bank accounts, sum of balances and “max account”
private double sum;
private BankAccount maximum; private int count;
public DataSet() {
// bank account with highest balance
-sum: double
-maximum: BankAccount
-count: int
+add(x: BankAccount): void
+getAverage(): double
+getMaximum(): BankAccount
public void
maximum = null;
count = 0; add(BankAccount x)
sum = sum + x.getBalance();
if(count == 0 || maximum.getBalance() < x.getBalance()) maximum = x; count++;
BankAccount
-accountNumber: int
-balance: double
+getBalance(): double +getAccountNumber(): int +withdraw(amount: double): void +deposit(amount: double): void
public double getAverage() {
if(count == 0) return 0; else return sum / count;
public BankAccount getMaximum() {
return maximum;
How about other types?
• For example, coins?
– DataSet to compute information for a set of coins – Coin instead of BankAccount
-sum: double -maximum: BankAccount -count: int
+add(x: BankAccount): void +getAverage(): double +getMaximum(): BankAccount
-faceValue: double
-name: String
+getFaceValue(): double
+getName(): String
How about data about coins?
public class DataSet {
private double sum; private Coin maximum; private int count;
public DataSet() {
// modified for Coin objects
// not only value but coin with highest face value
-sum: double
-maximum: Coin
-count: int
+add(x: Coin): void
+getAverage(): double
+getMaximum(): Coin
public void
sum = 0; maximum = null; count = 0;
add(Coin x)
sum = sum + x.getFaceValue();
if(count == 0 || maximum.getFaceValue() < x.getFaceValue()) maximum = x; count++;
public double getAverage() {
if(count == 0) return 0; else return sum / count;
public Coin getMaximum() {
-value: double
-name: String
+getFaceValue(): double
+getName(): String
return maximum;
What we have done so far
-sum: double
-maximum: BankAccount
-count: int
+add(x: BankAccount): void
+getAverage(): double
+getMaximum(): BankAccount
-sum: double
-maximum: Coin
-count: int
+add(x: Coin): void
+getAverage(): double
+getMaximum(): Coin
Is there a better way?
Works for BankAccount objects
DataSet Works for Coin objects Etc.
Compare method add() in class DataSet
public void add(BankAccount x) // DataSet.add() for BankAccount {
sum = sum + x.getBalance();
if(count == 0 || maximum.getBalance() < x.getBalance()) maximum = x; count++;
public void add(Coin x) // DataSet.add() for Coin {
sum = sum + x.getFaceValue();
if(count == 0 || maximum.getFaceValue() < x.getFaceValue()) maximum = x; count++;
Details for how “measurements” (balance, face value) are obtained differ.
Bank accounts: getMeasure() returns balance
Can all classes agree on a method (e.g., getMeasure()) that obtains required measure for any “measurable” object?
Coins:getMeasure() returns coin face value
public void add(BankAccount x) // DataSet.add() for BankAccount {
sum = sum + x.getBalance();
if(count == 0 || maximum.getBalance() < x.getBalance()) maximum = x; count++;
public void add(Coin x) // DataSet.add() for Coin {
sum = sum + x.getFaceValue();
if(count == 0 || maximum.getFaceValue() < x.getFaceValue()) maximum = x; count++;
public void add(??? x) // generic DataSet add() {
sum = sum + x.getMeasure();
if(count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++;
Generic version of add() in DataSet
public void add(??? x) {
sum = sum + x.getMeasure();
if(count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++;
What is x, maximum?
-sum: double -maximum: ? -count: int
+add(x: ?): void +getAverage(): double +getMaximum(): ?
x and maximum should refer to any class that has a getMeasure() method
The answer
x and maximum should refer to any class that has a getMeasure() method
public interface Measurable {
double getMeasure();
Interface types specify required operations
What do we need to do?
• Write interface Measurable (in file Measurable.java) – Specify methods used by all classes (see previous slide)
• Write “generic” class DataSet
– Uses methods from interface Measurable (i.e., getMeasure())
-sum: double -maximum: Measurable -count: int
+add(x: Measurable): void +getAverage(): double +getMaximum(): Measurable
• Write classes (e.g., BankAccount, Coin) that use DataSet – Implement methods from interface Measurable
Write DataSet
public interface Measurable {
double getMeasure();
public class DataSet {
private double sum; private Measurable maximum; private int count;
public DataSet() {
public void
sum = 0; maximum = null; count = 0;
add(Measurable x)
sum = sum + x.getMeasure();
if(count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++;
public double getAverage() {
if(count == 0) return 0; else return sum / count;
public Measurable getMaximum() {
return maximum;
-sum: double -maximum: Measurable -count: int
+add(x: Measurable): void +getAverage(): double +getMaximum(): Measurable
public interface Measurable {
double getMeasure();
Write BankAccount
public class BankAccount implements Measurable {
// BankAccount class variables
public double getMeasure() {
return balance;
// other BankAccount methods
BankAccount
-accountNumber: int
-balance: double
+getBalance(): double
+getAccountNumber(): int +withdraw(amount: double): void +deposit(amount: double): void +getMeasure(): double
public interface Measurable {
double getMeasure();
Write Coin
public class Coin implements Measurable {
// Coin class variables
public double getMeasure() {
return faceValue; // other Coin methods
-faceValue: double
-name: String
+getFaceValue(): double +getName(): String +getMeasure(): double
Using add()
public void add(Measureable x) // in DataSet {
sum = sum + x.getMeasure();
if(count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++;
public class DataSetManager {
DataSet bankAccounts = new DataSet(); DataSet coinCollection = new DataSet();
BankAccount b = new BankAccount(); Coin c = new Coin();
bankAccounts.add(b); coinCollection.add(c);
By implementing Measurable, BankAccount and Coin promise a certain behaviour and “compliance with contract”
Alternative?
BankAccount
-accountNumber: int
-balance: double
+getBalance(): double
+getAccountNumber(): int
+withdraw(amount: double): void
+deposit(amount: double): void
BankAccountSet
-sum: double
-maximum: BankAccount
-count: int
+add(x: BankAccount): void
+getAverage(): double
+getMaximum(): BankAccount
-sum: double -maximum: Coin -count: int
+add(x: Coin): void +getAverage(): double +getMaximum(): Coin
-value: double -name: String
+getValue(): double
+getName(): String
• Both implement the same thing
• Requires “set” class for each type of data • Consequences
• Redundancy
• Low reusability and maintainability
• Interfaces separate specification from implementation
– Interface must provide full method declaration (only abstract methods)
• Name, parameters, return type, etc.
• Methods are public
• Defined in separate .java files (e.g., Measurable.java)
– Noinstancevariables(maybeconstants1)
– Cannotbeinstantiated
• A class must implement interface
– “User” (client) of interface implements interface
– Compiler enforces implementation of interface methods
– Promises behavior defined in interface
1 Constants in interfaces are automatically public static final, see for example javax.swing.SwingConstants
1. Introduction to interface classes in Java
2. Interfaces in UML
3. Other interesting features of interfaces
Interfaces in UML – dependencies
• Denoted by stereotype <
• “Realises” relationship
– Dottedarrow
– Unfilledtrianglehead(interface)
<
+getMeasure(): double
• Lollipop notation
– Useful when interface not in diagram
BankAccount
Measurable
BankAccount
DataSet example in UML
“uses” because attributes / methods of DataSet require type Measureable
<
BankAccount Coin
DataSetManager
1. Introduction to interface classes in Java
2. Interfaces in UML
3. Interesting features of interfaces
Conversion between classes + interfaces
• Example – ok
BankAccount b = new BankAccount(…);
// legal to convert class to interface type that it implements Measurable m1 = b;
Measurable m2 = new BankAccount();
// m1, m2 could only invoke getMeasure()
Measurable m3 = new BankAccount(); System.out.println(“m3.getMeasure(): ” +m3.getMeasure());
BankAccount d = (BankAccount)m3;
// need to cast explicitly (otherwise compiler error)
d.setBalance(5);
// can invoke other methods from BankAccount
// prints 0.0
System.out.println(“d.getBalance(): ” +d.getBalance()); // prints 5.0
• Example – not ok
Measureable m = new Measurement(); // cannot instantiate interface BankAccount b = new Measurement(); // cannot instantiate interface
Interfaces and collections
• Collections use interfaces
– Collection: object that represents group of objects
• See previous lecture
– Types: Lists (e.g., ArrayList), sets (e.g., HashSet), maps (e.g., HashMap)
• Collection implementations – examples
ArrayList
Resizable array Hash table Doubly linked list Hash table with keys and values
• More about collections and types of collections in the lab
<
<
<
<
Collection examples – use cases of interfaces
Fast slide
Mapping of key + value
No duplicates
Typically FIFO Advanced operations
<
Can use enhanced for-each:
for(T : this)…
No assumptions about order or if it can contain duplicates
<
<
<
<
<
<
<
<
<
• More about collections and types of collections in the lab
1. Introduction to interface classes in Java
2. Interfaces in UML
3. Interesting features of interfaces
Cartoon of the day
Key lesson: Interfaces in Java act as “contract” between the user of a class and the “implementing” class. By implementing an interface, a class promises to provide behaviour specified in the interface.
Example – Painter (introduction)
• The following notes discuss another example to illustrate the use of interfaces.
• Students are encouraged to study the example in their own time and discuss any questions with teaching staff (e.g., in the lab).
• Students are also encouraged implement the full program in Java (based on the hints provided in the example). The solution will consist of at least the following classes:
– Painter, Paintable, Circle, Square, Rectangle
Self-study
Example – Painter (1)
• Painter: class to paint any type of object
• Painter has list of objects it wants to paint
– List of objects as property of class Painter
• E.g., property of type ArrayList
• What is type of ArrayList?
• Goal: Painter can add objects of different types to list – Circles(classCircle)
– Squares (class Square)
– Rectangles (class Rectangle)
Self-study
• Painter should be able to paint all objects in list (ArrayList) 32
Example – Painter (2)
• Without interface (bad solution)
Self-study
– Painter would need method for each to paint each type of object, e.g., • paintCircles()
• paintSquares()
• paintRectangles()
– Painter would need new ArrayList for each type of objects to paint • ArrayList
• ArrayList
• ArrayList
• Introduce interface Paintable (better solution)
– Leaves how objects are painted to classes that implement interface • Let classes Circle, Square, Rectangle implement Paintable
Example – Painter (3)
• If we use interface Paintable
Self-study
– Listofpaintableobjects(ourArrayList)wouldholdanypaintableobject • ArrayList
– If we need add object to paint, only create a new class • New class implements Paintable
• Painter never has to change
• Painter does not depend on objects it is going to paint
• Interface allows us to more easily develop with other people
– One developer can work on the Painter objects
– Another developer can work on the paintable objects
– To function properly together, need a common interface beforehand
Example – Painter (4)
Self-study
<
+paint(): void
-paintableObjects:ArrayList
+addObject(toPaint: Paintable):void +paintAllObjects():void
-width:int
-height:int
+paint():void
+updateWidth(aWidth:int):void
+updateHeight(aHeight:int):void
-sideLength:int
+paint():void
+updateSideLength(aSideLength:int):void
-radius:int
+paint():void
+updateRadius(radius:int):void
Example – Painter (5)
• How to use -study
– CreateinstanceofPainter,i.e.,Painterp=newPainter();
– Createpaintableobjects,e.g.,
• Circle c = new Circle(5);
// assuming constructor of Circle requires radius
• Square s = new Square(7);
// assuming constructor of Square requires side length
• Rectangle r = new Rectangle(6, 8);
// assuming constructor of Rectangle requires with, height
– Add objects to painter (p of type Painter) • p.addObject(c);
• p.addObject(s);
• p.addObject(r);
– Paintobjects,i.e.,p.paintAllObjects();
Example – Painter (6)
• Implementation of addObject(toPaint: Paintable) paintableObjects.add(toPaint);
// paintableObjects is ArrayList in Painter
• Implementation of paintAllObjects() – LooptovisitallobjectsinpaintableObjects
• For each object call paint(), e.g., paintableObjects.get(i).paint();
• Implementation of paint()
– Fortesting:System.out.println(“Printingcircle…”)maysuffice
– To “paint” on console/terminal
• In Circle: print * depending on the radius (using a loop)
• In Square: print * depending on the side length (using nested loop)
• In Rectangle: print * depending on width and height (using nested loop)
Self-study
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com