Interfaces, Lists and Generics

advertisement
Java Interfaces, Lists and
Generics essentials
SOFTENG 251
Object Oriented Software Construction
Announcements
 Make sure you filled in last Friday’s session reports
 Assignment 2 (due 24th April)
 Demonstrate your work & understanding in lab
 Code correctness – either in lab or through dropbox
 Some updates to Wiki
 Additional resource link: Java Developers Almanac
http://www.exampledepot.com/ - check it out!
 Exercise Bank – offline programming exercises;
Utilise tutorial to go over any of these + assignment
 Lecture debriefing – anything I missed out during a particular
lecture/Friday session, or you didn’t get a chance to ask
 Also Dols008’s lecture clarifications for Richard’s lectures
Generics in Java
SOFTENG 251 Object Oriented Software Construction
2
Java Interfaces
 Interfaces are special “classes” with only abstract methods
 i.e. über-abstract classes if you will
 One major distinction: a class can “extend” (implement) multiple
interfaces
 So what good is a “class” with no real methods?
 Interfaces are useful for defining a “signature”, or a “contract” of its
implementing classes
 i.e. the methods in the interface define what the implementing class
should do, i.e. expected to do
 Also a “cheap” way of supporting multiple inheritance
Generics in Java
SOFTENG 251 Object Oriented Software Construction
3
Flyer interface
 All birds can fly – so can some mammals
 But you can’t extend from both mammals
and bird  introduce a Flyer interface
public class Bird extends Animal
implements Flyer {
public void fly() {
System.out.println("Don’t look down");
} //etc...
}
public class FlyingSquirrel extends Mammal
implements Flyer {
public void fly() {
System.out.println("Wheeee!!");
} //etc...
}
Flyer[] flyers = new Flyers[2];
flyers[0] = new FlyingSquirrel("Yippee");
flyers[1] = new Bird();
for (Flyer flyer : flyers) { flyer.fly(); }
Generics in Java
public interface Flyer {
public void fly();
}
Flyer
<<interface>>
Mammal
+fly()
FlyingSquirrel
Bird
#name
-age
+fly()
+makeSound()
+fly()
+getAge()
SOFTENG 251 Object Oriented Software Construction
4
More Interface facts
 In a Java interface, you:
 can only define public abstract methods
(if it’s not explicitly declared public or abstract, compiler automatically
makes it so)
 can’t define instance variables
 can only define public, static and/or final variables
 Rules of inheritance and polymorphism apply to interfaces just as
they do to normal classes
 e.g. an interface can inherit from another interface!
public interface FastFlyer extends Flyer {
public void hyperdrive();
}
 Class implementing FastFlyer must implement both fly() and hyperdrive()
Generics in Java
SOFTENG 251 Object Oriented Software Construction
5
Interface java.util.List
 Java’s version of the list data
structure
 (non-generic – Java 1.4)
 This interface defines a
contract for each of the
operations of a list, i.e.
 What it takes in
 What it returns
 What the state of the list
should be afterwards
public interface List {
public boolean add(Object o);
public boolean add(int i, Object);
public Object remove(int i);
public Object remove(Object o);
public Object get(int i);
public int indexOf(Object o);
public boolean contains(Object o);
public int size();
public Iterator iterator();
//plus others
}
 Up to actual implementers to fulfil the contract – in whatever way
 ArrayList, Vector (retrofitted)
 LinkedList
 ShoppingList
Generics in Java
SOFTENG 251 Object Oriented Software Construction
6
List operations & contracts
add(x)
true
remove(c)
true
a b c d
x
0
4
1
2
1
2
a b c d
2
3
a b c
x
d
0
3
4
indexOf(c)
2
2
a b c d
size()
4
1
2
indexOf(x)
-1
a b c d c
0
contains(x)
false
1
0
3
?
1
remove(1)
b
3
a b c d
0
Generics in Java
3
a b c d c
0
contains(b)
true
2
remove(x)
false
0
get(3)
d
1
add(3,x)
true
1
2
3
4
4
a b c d
0
1
2
SOFTENG 251 Object Oriented Software Construction
3
7
ArrayList & LinkedList
…
a b c d e
0
1
2
3
4
5
6
public class ArrayList
implements List {
private Object[] elementData;
private int size;
... //etc
public boolean add(Object o) {
elementData[size++] = o;
return true;
}
public Object get(int i) {
return elementData[i];
}
public int size() {
return size;
}
... //etc
}
Generics in Java
a
b
c
d
e
0
1
2
3
4
public class LinkedList
implements List {
private Entry header;
private int size;
... //etc
public boolean add(Object o) {
addBefore(o,header);
return true;
}
public Object get(int i) {
return entry(i).element;
}
public int size() {
return size;
}
... //etc
}
SOFTENG 251 Object Oriented Software Construction
8
List and its implementations
 ArrayList and LinkedList override
each of the abstract methods in List
 In overriding each method, both
implementations satisfy the same
contract but through very different
means. E.g.
List
ArrayList’s remove(x):
<<interface>>
 shift all elements
from indexOf(x) + 1
to the left; size-LinkedList’s remove(x):
 relink x’s previous
node with x’s next
node; size--
+add(Object):boolean
+remove(Object):boolean
+get(int):Object
+indexOf(Object):int
+contains(Object):boolean
+size():int
+iterator():Iterator
etc…
 Both cases: list now is a concatenation of all
elements before x and all elements after x.
Generics in Java
ArrayList
-instance variables…
+add(Object):boolean
+remove(Object):boolean
+get(int):Object
+indexOf(Object):int
+contains(Object):bool
+size():int
+iterator():Iterator
etc…
LinkedList
-instance variables…
+add(Object):boolean
+remove(Object):boolean
+get(int):Object
+indexOf(Object):int
+contains(Object):bool
+size():int
+iterator():Iterator
etc…
SOFTENG 251 Object Oriented Software Construction
9
Programming scenario
 Say we are writing a (very) simple personal “library” manager
 Organise a collection of items – books, movies, CD’s, etc.
 List items, sort items, add/remove items to library, etc
 We need some kind of collection to store these items
 Let’s use a List  ArrayList to be precise
MyLibrary
List
Book
Generics in Java
Item
Movie
Priced
<<interface>>
CD
SOFTENG 251 Object Oriented Software Construction
Shirt
10
public class Item {
protected String title;
public Item(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
}
public class Movie extends Item {
private int year;
public Movie(String title,
int year) {
super(title);
this.year = year;
}
public int getYear() {
return year;
}
public String toString() {
return "Movie: " + title +
" (" + year + ")";
}
}
Generics in Java
public class Book extends Item {
private String author;
public Book(String title,
String author) {
super(title);
this.author = author;
}
public String getAuthor() {
return author;
}
public String toString() {
return "Book: '" + title +
“' by " + author;
}
}
public class CD extends Item
implements Priced {
...
public String getPrice() {...}
}
public interface Priced {
public double getPrice();
}
SOFTENG 251 Object Oriented Software Construction
11
A list of Items
Book book = new Book("LOTR","Tolkien");
Movie movie = new Movie("Psycho",1960);
CD cd = new CD("Ozomatli",2.50);
List items = new ArrayList();
items.add(book); //element #0
items.add(movie); //element #1
items.add(cd);
//element #2
Book b = (Book)items.get(0); Item
bookAsItem = (Item)items.get(0);
Movie m = (Movie)items.get(1);
Priced forSale = (Priced)items.get(2);
public interface List {
public boolean add(Object o);
public Object get(int i);
public int size();
//etc...
}
Generics in Java
Thanks to polymorphism:
 Variable item of type
List can point to a
value of type ArrayList
 We can pass in a Movie
or Book as argument to
add() as it accepts an
Object
 However because get()
returns an Object, we
need to downcast the
result to the
appropriate subtype
SOFTENG 251 Object Oriented Software Construction
12
List of Item’s
public static void main(String[] args) {
List items = new ArrayList();
populate(items);
list(items);
}
public static void populate(List items) {
items.add(new Movie("Psycho",1960));
items.add(new Book("LOTR","Toklien"));
}
 We want items to
only have objects of
type Item (or its
subclasses)
 What happens if it
doesn't?
public static void list(List items) {
for (int i = 0; i < items.size(); i++) {
Item item = (Item)items.get(i);
System.out.println(i+": "+item.getTitle());
}
}
Generics in Java
SOFTENG 251 Object Oriented Software Construction
13
Type safety
public static void main(String[] args) {
List items = new ArrayList();
populate(items);
list(items);
}
 What exactly would
happen?
 (Will this compile?)
public static void populate(List items) {
items.add(new Movie("Psycho",1960));
items.add("Terminator"); //String!
}
public static void list(List items) {
for (int i = 0; i < items.size(); i++) {
Item item = (Item)items.get(i);
System.out.println(i+": "+item.getTitle());
}
}
Generics in Java
SOFTENG 251 Object Oriented Software Construction
14
Compile-time vs. Runtime errors
 Moral of the story: we can’t rely on the compiler to detect/predict all
errors (although we’d like to)
 What compilers can detect:
 Syntactic/”obvious” errors, e.g: accessing an undeclared variable; calling
an undefined method; mismatching braces/brackets; assigning a value to
a variable of incompatible type
 What compilers can't:
 Logical errors, unexpected behaviours only observable at runtime e.g.
accessing a null field, bogus user input, nondeterministic code
 Most lead to exceptions being thrown like NullPointerException,
ArrayIndexOutOfBoundsException, NumberFormatException,
ClassCastException
Generics in Java
SOFTENG 251 Object Oriented Software Construction
15
What can we do instead?
 Create a specialised List for Item?
public class ItemList {
 Repetitive
private List items;
public boolean add(Item o) {
 Inefficient
items.add(o);
}
 Hardly scalable
...
public Item get(int i) {
return (Item) items.get(i);
}
public class StringList {
}
private List items;
public boolean add(String s) {
items.add(s);
}
...
public String get(int i) {
return (String)items.get(i);
}
public class IntList {
private List items;
public boolean add(Integer i) {
items.add(i);
}
...
public Integer get(int i) {
return (Integer)items.get(i);
}
}
}
Generics in Java
SOFTENG 251 Object Oriented Software Construction
16
Answer: Generics!
 With generics, we can make List a generic type
 By parameterising List with the type Item we are guaranteed that
any instance of this special List would only contain objects of type Item
(or its subclasses)
public class List<E> {
public boolean add(E o);
public E get(int i);
public int size();
}
Translation: List is a generic
type, and it has one type
parameter, which we call E
List<Item> items = new ArrayList<Item>();
...
items.add(new Movie("Psycho",1960));
...
for (int i = 0; i < items.size(); i++) {
Item item = items.get(i);
...
Generics in Java
No casting necessary
SOFTENG 251 Object Oriented Software Construction
17
Generic ArrayList
 Basically, all occurrences of
Object are “replaced” by the
type variable E
 Think of E as a placeholder for
any possible type – just as a
variable is a place-holder for
any possible value
 Type variables can have any
name – we just chose E
because it’s nice and short
 Type variables themselves can
be used to parameterise other
generic types! (i.e. List<E>)
Generics in Java
public class List<E> {
public boolean add(E o);
public E get(int i);
public int size();
}
public class ArrayList<E>
implements List<E> {
private E[] elementData;
private int size;
... //stuff
public boolean add(E o) {
elementData[size++] = o;
return true;
}
public E get(int i) {
return elementData[i];
}
public int size() {
return size;
}
}
SOFTENG 251 Object Oriented Software Construction
18
Generics and type safety
 Good news: the compiler
can help us prevent type
errors
 The compiler enforces
the parameterised type
List<Item> to only
accept and return
instances of Item (or its
subclasses)
COMPILE-TIME
ERROR
Generics in Java
public static void main(String[] args) {
List<Item> items = new ArrayList<Item>();
populate(items);
list(items);
}
static void populate(List<Item> items) {
items.add(new Movie("Psycho",1960));
items.add("Terminator");
}
static void list(List<Item> items) {
for (int i = 0; i < items.size(); i++) {
Item item = items.get(i);
System.out.println(i+": "+item.getTitle());
String wtf = (String)items.get(i);
}
}
SOFTENG 251 Object Oriented Software Construction
19
Review of lingo
‘Generic type’
‘Type parameter’
/‘Type variable’
public class Arraylist<E> {
private E[] elementData;
... //stuff
public boolean add(E o) {
elementData[size++] = o;
return true;
}
public E get(int i) {
return elementData[i];
}
}
‘Non-generic type’
public class ArrayList {
private Object[] elementData;
... //stuff
public boolean add(Object o) {
elementData[size++] = o;
return true;
}
public Object get(int i) {
return elementData[i];
}
}
‘Parameterised type’
List<Item> items = new ArrayList<Item>();
‘Type argument’
Generics in Java
SOFTENG 251 Object Oriented Software Construction
20
Type variables/parameters
Provide Item as type argument
new ArrayList<Item>()
value of type parameter E becomes Item
public class ArrayList<E> {
private E[] elementData;
... //stuff
public boolean add(E o) {
elementData[size++] = o;
return true;
}
public E get(int i) {
return elementData[i];
}
}
Generics in Java
Provide "Hello" as argument
print("Hello");
value of variable str becomes "Hello"
private void print(String str) {
...
int ln = str.length();
...
...
System.out.println(str);
}
SOFTENG 251 Object Oriented Software Construction
21
Generic methods
 Define generic methods just as you define generic classes
 Example: reverse the elements from a given vector
 E.g. [a,b,c,d,e]  [e,d,c,b,a]
List<Movie> movies = new ArrayList<Movie>();
List<String> words = new ArrayList<String>();
populate(movies); populate(words);
List<Movie> seivom = reverse(movies);
List<String> sdrow = this.<String>reverse(words);
Note the “proper” way of
public<T> List<T> reverse(List<T> list) {
List<T> rev = new ArrayList<T>();
calling a generic method
for (int i = list.size() - 1; i >= 0; i --) { is to parameterise it like
T item = list.get(i);
this. However usually the
rev.add(item);
compiler can infer the
}
type in question, allowing
return rev;
us to omit this construct.
}
Generics in Java
SOFTENG 251 Object Oriented Software Construction
22
(Non-generic alternative)
 Looks simpler!
 But realise obviously you won’t be able to retain type information
using this method
List movies = new ArrayList();
List words = new ArrayList();
populate(movies); populate(words);
List seivom = reverse(movies);
List sdrow = reverse(words);
public List reverse(List list) {
List rev = new ArrayList();
for (int i = list.size() - 1; i >= 0; i --) {
Object item = list.get(i);
rev.add(item);
}
return rev;
}
Generics in Java
SOFTENG 251 Object Oriented Software Construction
23
Generic methods
 Bounded type parameters (e.g. <T extends Item>) allow restriction on
type arguments
 Below: [Art,Bam,Apples,Crab,argh,Ache]  [Art,Apples,Ache]
List<Movie> movies = new ArrayList<Movie>();
List<String> words = new ArrayList<String>();
populate(movies); populate(words);
List<Movie> moviesA = startsWithA(movies);
List<String> wordsA = startsWithA(words);

public<T extends Item> List<T> startsWithA(List<T> list) {
List<T> filtered = new ArrayList<T>();
for (int i = 0; i < list.size(); i ++) {
T item = list.get(i);
if (item.getTitle().startsWith(“A”)) {
filtered.add(item);
Notice how we can call getTitle()
}
on item, because we know from the
}
type parameter T’s declaration that it
return filtered;
extends Item
}
Generics in Java
SOFTENG 251 Object Oriented Software Construction
24
(Aside) Multiple type bounds
 Can use ‘&’ operator to define multiple type bounds
List<Movie> movies = new ArrayList<Movie>();
List<CD> cds = new ArrayList<CD>();
...
pricedItems(movies);
Movie is a subclass of Item, but not Priced
pricedItems(cds);

public<T extends Item & Priced> void pricedItems(List<T> list) {
for (int i = 0; i < list.size(); i ++) {
T item = list.get(i);
System.out.print("Loaning " + item.getTitle());
System.out.println(" at price " + item.getPrice());
}
Notice how item (of type T) can now access all methods
}
belonging to Item and Priced
public interface Priced {
public double getPrice();
}
Generics in Java
public class CD extends Item
implements Priced {
...
SOFTENG 251 Object Oriented Software Construction
25
Try it yourself
 Revise lecture code examples
 Exercises in Wiki
 Writing a generic Pair<E1,E2>
 Writing a Chain<E> data structure
 A simple differencing tool
 Useful examples in the Java Almanac (see link from Wiki)
Generics in Java
SOFTENG 251 Object Oriented Software Construction
26
Tutorial idea
 Hands-on Generics: understanding what is/isn't possible with
Generics.
 Observing compiler outputs. Focus on using generic types. List and
HashMap good examples.
 The basics: compiler warnings with non-generic types, (good)
compiler errors resulting from enforced generic types.
 Sub-typing: showing sub-typing of parameterised types acts
differently from sub-typing of normal types
 Bounded and unbounded wildcards: how sub-typing can be done
using these mechanisms
Generics in Java
SOFTENG 251 Object Oriented Software Construction
27
Download