Interfaces Java Bruce Eckel, Thinking in Java, 4th edition, PrenticeHall, New Jersey, cf. http://mindview.net/Books/TIJ4 [email protected] José Valente de Oliveira 11-1 Overview Java interfaces [email protected] An introduction Sintaxe UML notation Multi-inheritance of interfaces (Some) Java pre-defined interfaces Design pattern: Strategy José Valente de Oliveira 11-2 1 Recall: Data type definition A data type is a set of values and a collection of operations on the set of values. Example: The int data type has the following set of values { …, -2, -1, 0, 1, 2, … }, and operations on these values such as: +, *, etc. [email protected] José Valente de Oliveira 4-3 Recall: Abstract Data Type definition An ADT (abstract data type) is a data type whose values are only available to clients through the operations in the ADT interface In C, a string is not an ADT. Why? [email protected] José Valente de Oliveira 4-4 2 Recall: Some advantages of ADT 1. 2. 3. 4. 5. 6. Clients of an ADT do not know the representation therefore do not mess up the representation Even if implementation changes, as long as the interface remains stable, no changes are required in the client. It is easy to ensure invariants, The user of an ADT can focus on the problem domain and forget about representation and implementation details. We have now ADT that can be easily reused in other problems An ADT based program is (much) more stable than another based solely on procedures/functions. [email protected] José Valente de Oliveira 4-5 Even in problems as simple as the distance between 2 points ADT can be useful. [email protected] José Valente de Oliveira 11-6 3 The interface IPoint interface IPoint { int getX(); int getY(); void setX(int x); void setY(int y); double dist(IPoint p); } [email protected] José Valente de Oliveira 11-7 Class CartPoint implements IPoint class CartPoint implements IPoint { private int x, y; public CartPoint (int a, int b) {setX(a); setY(b); } public int getX() {return x;} public int getY() {return y;} public void setX(int a) { assert a>=0; x=a; } public void setY(int b) { assert b>=0; x=b; } public double dist(IPoint p) { int dx = x – p.getX(); int dy = y – p.getY(); return Math.sqrt(dx*dx+dy*dy); } } [email protected] José Valente de Oliveira 11-8 4 A client public class Client { public static void main(String[] args) { IPoint A, B; A = new CartPoint(1, 1); B = new PolarPoint(4, 2); System.out.println(A.dist(B)); } } [email protected] José Valente de Oliveira 4-9 Recall Type relates to behaviour while class relates to implementation. Two objects from the same class have necessarily the same type. Two objects from the same type (e.g. IPoint) can be instances from different classes (e.g., CartesianPoint, PolarPoint) [email protected] José Valente de Oliveira 11-10 5 Revisiting the notion of class From the modeling perspective, a class describes a set of objects with the same semantics (the same role in the program), i.e., with the same: Properties (data structure); Behaviour (functions), and Relationships [email protected] José Valente de Oliveira 3-11 Classes, again A class is a (possibly partial) implementation of a data type. [email protected] José Valente de Oliveira 11-12 6 The Stack ADT A stack is a last-in-first-out (LIFO) data structure Adding an item Referred to as pushing it onto the stack Removing an item Referred to as popping it from the stack 13 The Stack ADT An ordered collection (list) of data items, that can be accessed at only one end (the top) of the collection Basic operations, informally: create a stack (usually empty) check if it is empty Push: add an element to the top (if it is not full) Top: retrieve the top element (if it is not empty) Pop: remove the top element (if is not empty) 14 7 @SuppressWarnings(“unchecked”) interface IStack { int DEFAULT_SIZE=12; /** * PRE: isEmpty() == false * POS: this == old this */ Object top(); /** * PRE: isEmpty() == false * POS: isFull() == false */ Object pop(); /** * PRE: isFull() == false * POS: isEmpty() == false && obj == top() */ void push(Object obj); [email protected] Example: interface IStack interface IStack<T> { int DEFAULT_SIZE=12; /** * PRE: isEmpty() == false * POS: this == old this */ T top(); /** * PRE: isEmpty() == false * POS: isFull() == false */ T pop(); /** * PRE: isFull() == false * POS: isEmpty() == false && o == top() */ void push(T obj); José Valente de Oliveira 11-15 Example: interface IStack /** * PRE: true * POS: responde um inteiro com o tamanho actual do stack */ int size(); /** * PRE: true * POS: responde true se o stack está vazio; responde false caso contrário */ boolean isEmpty(); /** * PRE: true * POS: responde true se o stack está cheio; responde false caso contrário */ boolean isFull(); } [email protected] José Valente de Oliveira 11-16 8 AStack implements IStack class AStack implements IStack { //… } //… IStack s; s = new IStack (); // ERROR ! s = new AStack(); // OK [email protected] José Valente de Oliveira 11-17 Sintaxe Qualif* interface Ident [extends Ident] [, Ident]*] { [Qualif* Type Ident = expression;]* [Qualif* Type Ident] ([Type Ident [, Type Ident]*); ]* [email protected] Qualf Ident qualificador Identifier (name) José Valente de Oliveira 11-18 9 UML notation [email protected] José Valente de Oliveira 11-19 University people class diagram, again [email protected] José Valente de Oliveira 11-20 10 A poor solution for multi-inheritance [email protected] José Valente de Oliveira 11-21 A poor solution for multi-inheritance class Test { private static void f(Trabalhador t) { System.out.println (t.obtemSalário()); } public static int main(String [] args) { EstudanteComSalário ecs = new EstudanteComSalário(); f(ecs); // ERRO !!! } } [email protected] José Valente de Oliveira 11-22 11 Multi-inheritance of interfaces [email protected] José Valente de Oliveira 11-23 Declaring the interfaces interface IPessoa { int nbi(); String nome(); String morada(); } interface IEstudante extends IPessoa { int número(); } interface ITrabalhador extends IPessoa { int salário(); } interface ITrabalhadorEstudante extends IEstudante, ITrabalhador { } [email protected] José Valente de Oliveira 11-24 12 Implementing the classes class Pessoa { // … } class Estudante extends Pessoa implements IEstudante { //… } class Trabalhador extends Pessoa implements ITrabalhador { //… } class EstudanteComSalário extends Estudante implements ITrabalhadorEstudante { // … } [email protected] José Valente de Oliveira 11-25 Required changes in the previous code class Test { private static void f(Trabalhador t) { System.out.println (t.obtemSalário()); } public static int main(String [] args) { EstudanteComSalário ecs = new EstudanteComSalário(); f(ecs); // ERRO !!! } } [email protected] José Valente de Oliveira 11-26 13 Required changes in the previous code class Test { private static void f(ITrabalhador t) { System.out.println (t.obtemSalário()); } public static int main(String [] args) { ITrabalhorEstudante ecs = new EstudanteComSalário(); f(ecs); // OK !!! } } [email protected] José Valente de Oliveira 11-27 Java pre-defined interfaces [email protected] José Valente de Oliveira 11-28 14 Previously on POO: The Quicksort abstract class @SuppressWarnings(“unchecked”) abstract class Quicksort { private Comparable[] data; public final void quicksort(Comparable[] d) { data = d; quicksort(0, data.length-1); } / Java pre-defined interfaces Interface Comparable<T> { /** Answer a negative integer if the receiver is lower than the argument obj; answer 0 if both receiver and obj are equal; answer a positive integer is receiver is greater than obj */ int compareTo(T obj); } @Deprecated interface Comparable { /** Answer a negative integer if the receiver is lower than the argument obj; answer 0 if both receiver and obj are equal; answer a positive integer is receiver is greater than obj */ int compareTo(Object obj); } [email protected] José Valente de Oliveira 11-30 15 Example /** @version 3.0 */ class Fraction implements Comparable<Fraction> { private int num, den; // … public int compareTo (Fraction f) { double q = (double) num / (double) den ; double fq = (double) f.num /(double) f. den ; return ((int) Math.signum(q – fq)); } } [email protected] José Valente de Oliveira 11-31 Example public class Main { public static void main(String[] args) { Fraction [] a = {new Fraction(1, 7), new Fraction(5, 2), new Fraction(1, 2) }; ProbQuickSort<Fraction> pqs; pqs = new ProbQuickSort<Fraction>(); pqs.quicksort(a); for(int i=0; i< a.length; i++ ) System.out.println (a[i]); } } [email protected] José Valente de Oliveira 11-32 16 Pre-defined Java interfaces interface Cloneable {} [email protected] José Valente de Oliveira 11-33 Main methods of abstract superclass Object [email protected] protected Object clone() throws CloneNotSupportedException public boolean equals(Object obj) protected void finalize() throws Throwable public final Class<?> getClass() public String toString() José Valente de Oliveira 11-34 17 Example Interface IStack { int DEFAUL_SIZE = 10; //… } class AStack implements IStack, Cloneable { public AStack() { this(DEFAULT_SIZE); } public Object clone() { // TODO } // … } [email protected] José Valente de Oliveira 11-35 Check point: where is the error in the class Client? class Point implements IPoint { private int x, y; public Point (int a, int b) {setX(a); setY(b); } public int getX() {return x;} public int getY() {return y;} public void setX(int a) { assert a>=0; x=a; } public class Client { } public void setY(int b) { assert b>=0; x=b; public int dist(Point p) { public static void main(String[] args) { int dx = x – p.getX(); IPoint A, B; int dy = y – p.getY(); A = new IPoint(1, 1); B = new IPoint(4, 2); return (int) Math.sqrt(dx*dx+dy*dy); System.out.println(A.dist(B)); } } } } [email protected] José Valente de Oliveira 11-36 18 To take away today Java interfaces An introduction Sintaxe UML notation Multi-inheritance of interfaces (Some) Java pre-defined interfaces Coming soon: Design pattern: Strategy [email protected] José Valente de Oliveira 11-37 19