Download Lecture notes 3

Document related concepts
no text concepts found
Transcript
CE203 - Application Programming
Part 3
Autumn 2016
CE203 Part 3
1
Learning objectives today
•
•
•
•
•
Inheritance
Abstract classes
Interfaces
Java collections framework
Vectors
Autumn 2016
CE203 Part 3
2
Assignment 1
• Available on orb
(http://orb.essex.ac.uk/ce/ce203/syllabus.html)
• Deadline = Wednesday 9th November, 11:59:59
• 10% of module mark.
• Two exercises…
1) Write a GUI to display your name in different colours
2) Display an editable list of words in your GUI
Autumn 2016
CE203 Part 3
3
Inheritance 1
Suppose we have written a class Person
-store information about persons (e.g. name, date of birth)
We now wish to write a class to store information about students.
A student is a person (with some extra attributes such as a
registration number) so the class Student can be a subclass of
Person.
We can then apply methods from the Person class to objects of
type Student and also store objects of type Student in arrays or
other collections of persons.
Autumn 2016
CE203 Part 3
4
Inheritance 2
Person
-Name
-Date of birth
(String)
(int)
Student
-Name
-Date of birth
-RegNo
Autumn 2016
CE203 Part 3
(String)
(int)
(int)
5
Inheritance 3
public class Student extends Person
{
private int regno;
public Student(String s, Date d, int r)
{
super(s,d);
regno = r;
}
public int regNumber()
{
return regno;
}
public String toString()
{
return super.toString() + " Regno: “ + regno;
}
}
Autumn 2016
CE203 Part 3
6
Inheritance 4
To invoke the constructor from the superclass within the subclass
constructor we have used the super statement, which, if used,
must be the first statement in the constructor.
If there is no such statement the no-argument constructor of the
superclass will be invoked implicitly; if there is no such
constructor the compiler will report an error.
The keyword super has also been used to prefix the call of
toString to ensure that the Person version is called; if this prefix
was not used dynamic binding would result in a recursive call to
the Student version.
super.toString()
Autumn 2016
CE203 Part 3
7
Inheritance 5
Exercise…
Will this code cause an error?
public class Food
{
public Food( String Type )
{}
}
To fix, call super
Class Cheese extends Food
and provide a
{
string argument.
public Cheese
{
super(“hello”);
}
}
Autumn 2016
CE203 Part 3
Answer:
Yes it will.
The constructor for Food is
not explicitly called with
super, therefore a noargument version will be
called implicitly, no such
constructor exists (a String
argument is expected), so an
error will occur.
8
Inheritance 6
Since all students are persons a variable of type Person may
refer to an object of type Student:
Person harry = new Student(”Harry Potter”,
new Date(31,7,1980), 9907077);
If we were to apply toString to the variable harry the
student version would be called.
It is not legal to write
int r = harry.regNumber();
since, although we know that harry refers to a student, the
variable is of type Person and the Person class has no
regNumber method.
Autumn 2016
CE203 Part 3
9
Inheritance 7
To apply the regNumber method to a student referenced by a variable of
type person we must perform a downcast, telling the compiler that the
variable will refer to a subclass object.
int r = ((Student)harry).regNumber();
Note, the highlighted parentheses are necessary since method application
has a higher precedence than downcasting; without the parentheses the
downcast would be applied to the result of the regNumber call.
If the variable harry did not refer to a student an exception of type
ClassCastException would be thrown when the code was run.
Pointer
Autumn 2016
harry
Object
(type = Person)
(type = Student)
CE203 Part 3
10
Inheritance 8
Since a student is a person we may of course store students in an array of
objects of type Person.
Person[] a = new Person[4];
a[0] = new Person();
a[1] = new Student();
// etc.
If we have such an array and wish to process all of the students in the array
(but not non-students) we need to determine whether a particular element is a
student.
To do this we must use the instanceof operator, which tests whether a
superclass object is a member of a particular subclass.
Autumn 2016
CE203 Part 3
11
Inheritance 9
For example…
To print details of all students in an array a of objects of type
Person we could use:
for (int i = 0; i < a.length; i++)
if (a[i] instanceof Student)
System.out.println(a[i]);
Similarly, to print details of all non-students in the array we could
use:
for (int i = 0; i<a.length; i++)
if (!(a[i] instanceof Student))
System.out.println(a[i]);
Again the highlighted parentheses are essential.
Autumn 2016
CE203 Part 3
12
Inheritance 10
Since a student is a person an array of students is an array of
persons and we may use an array of students anywhere an array of
persons is expected.
Hence if Employee is a subclass of Person, but not of Student,
and s has been declared as an array of students, the following
code fragment is legal:
static void changeLast(Person[] p)
{
p[p.length-1] = new Employee(……);
}
……
changeLast(s);
……
Autumn 2016
CE203 Part 3
13
Inheritance 11
Warning!
Although the code on the previous slide will compile without
any problems it will not run successfully since we cannot
store an employee in an array of students. When we try to run
the code an exception of type ArrayStoreException will be
thrown.
Autumn 2016
CE203 Part 3
14
Inheritance 12
If a method has an argument of type Object[] , any array of objects
may be passed to it (but not an array of primitive values).
We can use this to write a method which will copy the contents of
one array into another:
static void arrCopy(Object[] source, Object[] dest)
{
if (dest.length<source.length)
{
throw new ArrayStoreException();
}
int i;
for (i = 0; i < source.length; i++)
{
dest[i] = source[i];
}
}
Autumn 2016
CE203 Part 3
15
Inheritance 13
The method works if…
-the element-types of the two arrays passed as arguments are the same
-the source array type is a subclass of the destination array type.
It will also work in certain other circumstances, as long as all
of the elements of the source array are of the correct type for
the destination. For example, we can copy an array of type
Person into an array of type Student if all of the people in
the array happen to be students, but an exception will be
thrown if any of the elements is not a student.
Autumn 2016
CE203 Part 3
16
Inheritance 14
Take away messages
References can be used to point to sub-classes
You can move classes into new variables if the new variable
is of the same type or a superclass of the variable
You can use instanceOf to check whether an object is a
superclass of another object.
Autumn 2016
CE203 Part 3
17
Abstract Classes 1
Abstract classes: a class that cannot be instantiated, only
inherited from.
The inheriting class can use methods from the abstract class.
The abstract class provides a common framework that
allows subclasses to be interchanged with other inheriting
subclasses.
Autumn 2016
CE203 Part 3
18
Abstract Classes 2
Suppose that we wish to write a program to draw and manipulate
simple shapes (circles, squares, etc.) on a frame.
We might write a square class to store information about squares.
public class Square
{
private Color
col;
private int
xpos, ypos; // centre coords
private int
slen;
// side length
public Square(Color c, int x, int y, int s)
{
col = c; xpos = x; ypos = y; slen = s;
}
Autumn 2016
CE203 Part 3
19
Abstract Classes 3
}
public void setColor(Color c)
{
col = c;
}
public void move(int xdist, int ydist)
{
xpos += xdist; ypos += ydist;
}
public void draw(Graphics g)
{
g.setColor(col);
g.drawRect(xpos-slen/2, ypos-slen/2,
slen, slen);
}
Autumn 2016
CE203 Part 3
20
Abstract Classes 4
Assume that we also have both Circle and Triangle
classes with setColor, move and draw methods and that
details of all of the shapes currently displayed are stored
in an array called shapes whose item-type is Object.
Suppose we wish to change the colour of all of the shapes
in the array to blue. We would like to write
for (int i = 0; i < shapes.length; i++)
shapes[i].setColor(Color.blue);
but cannot do this since the Object class has no method
called setColor.
Object shapes[];
Circle
Triangle
Circle
.
.
.
What’s the solution?
Autumn 2016
CE203 Part 3
21
Abstract Classes 5
The solution is to introduce a new class called Shape with a
setColor method and declare all of the shape classes as
subclasses of this class. We can then use an array of Shape
objects instead of an array of items of type Object.
The new class should be declared as an abstract class – this
means that all of its members must be instances of one of its
subclasses and explicit calls to new Shape(……) are not
allowed.
We never just have a ‘shape’, we have types of shapes,
e.g. Squares, Triangles etc.
We should place the attributes and methods that are common
to all shapes in the Shape class, as seen on the next slide.
Autumn 2016
CE203 Part 3
22
Abstract Classes 5
public abstract class Shape
{
protected Color
col;
protected int
xpos, ypos;
public Shape(Color c, int x, int y)
{
col = c; xpos = x; ypos = y;
}
public void setColor(Color c)
{
col = c;
}
}
public void move(int xdist, int ydist)
{
xpos += xdist; ypos += ydist;
}
Autumn 2016
CE203 Part 3
23
Abstract Classes 6
The instance variables have been declared as protected so that the
subclasses can access them in their draw methods.
Since the Square class will now inherit attributes and methods from
Shape it will be much more concise.
public class Square extends Shape
{
private int slen; // side length
public Square(Color c, int x, int y, int s)
{
super(c, x, y); slen = s;
}
}
public void draw(Graphics g) // as before
Autumn 2016
CE203 Part 3
24
Abstract Classes 7
Since the draw methods for each individual shape are different
they must be written in the individual classes.
However, to allow a loop such as
for (int i = 0; i<shapes.length; i++)
shapes[i].draw(g);
to be written, the abstract class Shape must have a draw method.
The use of dynamic binding means that this method will never be
called so we could simply write a method that does nothing.
However, the preferred approach is to declare the method as
abstract.
Autumn 2016
CE203 Part 6
25
Abstract Classes 8
public abstract class Shape
{
protected Color col;
protected int
xpos, ypos;
public Shape(Color c, int x, int y)
{
col = c; xpos = x; ypos = y;
}
// setColor and move methods as before
public abstract void draw(Graphics g);
}
Note that only abstract classes can have abstract methods.
Autumn 2016
CE203 Part 3
26
Interfaces 1
An interface is essentially an extreme example of an abstract
class – all of its methods are abstract. There are, however,
some significant differences between interfaces and abstract
classes:
• the only variables that an interface can have are public
static final ones (i.e. constants)
• an interface can not have any constructors
• a class does not inherit from an interface but instead is
said to implement it and uses the keyword implements
instead of extends
• Java 8 introduced default methods and static methods
(check the Java API!)
Autumn 2016
CE203 Part 3
27
Interfaces 2
The most common use of interfaces is to provide a
specification of the methods of a class that is to be used in
one package but implemented in different ways in many
others – ActionListener is a typical example; classes that
implement it are written by the programmer but used by
classes in the java.awt.event package.
A class may implement more than one interface:
class Silly implements ActionListener,
Collection, Comparable
Autumn 2016
CE203 Part 3
28
Abstract classes and Interfaces
Take away messages
-Abstract classes provide a template for sub-classes
-This can allow iteration over different objects that extend
the abstract class.
-Interfaces are extreme versions of abstract classes
-Interfaces provide class specifications for different uses in
different packages
Autumn 2016
CE203 Part 3
29
Inheritance vs. Composition 1
A word of caution!
Vehicle
Drinks
-TasteGreat()
-Drive()
Car
CoffeePlane
-Fly()
-TasteGreat()
-Drive()
-WakeUp()
Coffee
-WakeUp()
-TasteGreat()
-Park()
Tea
Plane
-TasteGreat()
-Brew()
-Fly()
-Drive()
With thanks to funfunfunction (https://www.youtube.com/watch?v=wfMtDGfHWpA)
Autumn 2016
CE203 Part 3
30
Inheritance vs. Composition 2
Composition allows you to create classes for particular functions. New classes can then be
created that included those classes as members.
e.g.
Classes
Fly
TasteGreat
WakeUp
New class:
CoffeePlane
Fly
TasteGreat
WakeUp
Autumn 2016
CE203 Part 3
31
Inheritance vs. Composition 3
class Fly
{
doFly()
{…}
}
class TasteGreat
{
produceFlavour()
{…}
}
class CoffeePlane
{
Fly
flying = new Fly();
TasteGreat taste = new TasteGreat();
}
Autumn 2016
CE203 Part 3
32
Quiz
• A quick quiz to test your knowledge
Kahoot.it
Autumn 2016
CE203 Part 3
33
Learning objectives today
•
•
•
•
•
Inheritance
Abstract classes
Interfaces
Java collections framework
Vectors
Autumn 2016
CE203 Part 3
34
Comparing Objects 1
Suppose we have a Date class and wish to compare some dates
that have been input with a specific date. If we try to use code
such as
Date xmasDay = new Date(25,12,2016);
Date theDay = Date.getDate();
if (theDay==xmasDay)
……
we will find that the result of the comparison is always false.
When comparing references to two objects they are regarded as
equal only if they refer to the same object.
Autumn 2016
CE203 Part 3
35
Comparing Objects 2
To determine if two objects have the same contents we should
use an equals method that compares the contents, overriding
the equals method inherited from the Object class:
if (theDay.equals(xmasDay))
……
To override the inherited version an equals method must
have an argument of type Object and downcast its argument.
An equals method for the Date class is provided on the next
slide.
Autumn 2016
CE203 Part 3
36
Comparing Objects 3
public boolean equals(Object o)
{
// check if the argument is a non-null date
if (o!=null && o instanceof Date)
{
Date arg = (Date)o;
return y==arg.y && m==arg.m && d==arg.d;
}
else
{
// if the argument isn’t a date they cannot
//
be equal
return false;
}
}
Autumn 2016
CE203 Part 3
37
Comparing Objects 4
Remember:
If you try to compare object references with == it will only
return true if both references point to the same object.
You will need to overwrite the equals function to compare
the contents of objects.
Autumn 2016
CE203 Part 3
38
The Java Collections Framework 1
A Java Collection is a framework that allows groups of objects to
be stored and manipulated.
The Java Collections framework provides a number of classes
that can be used to store various kinds of collections of objects.
These kinds are distinguished by properties such as whether
duplicate elements are allowed and whether the elements have a
defined order.
Methods that are common to all collection classes are declared in
an interface called Collection from the package java.util.
Autumn 2016
CE203 Part 3
39
Autumn 2016
CE203 Part 3
40
Autumn 2016
CE203 Part 3
41
The Java Collections Framework 2
public interface Collection
{
public boolean isEmpty();
public int size();
public boolean contains(Object o);
public boolean containsAll(Collection c);
public boolean add(Object o);
public boolean addAll(Collection c);
public void clear();
Autumn 2016
CE203 Part 3
42
The Java Collections Framework 3
public
public
public
public
public
public
public
public
boolean remove(Object o);
boolean removeAll(Collection c);
boolean retainAll(Collection c);
Object[] toArray();
Object[] toArray(Object[] a);
Iterator iterator();
int hashCode();
boolean equals(Object o);
}
Autumn 2016
CE203 Part 3
43
The Java Collections Framework 4
The contains and containsAll methods use equals to
compare elements; the latter returns true if the collection
contains at least one instance of each of the elements of the
argument.
The add method may fail if an attempt is made to add an
element that is already present to a collection that does not
allow duplicates; hence a result is returned to indicate whether
the addition was successful.
For the same reasons the addAll method may add to the
collection some, all or none of the elements in its argument; it
will return true if at least one element has been added.
Autumn 2016
CE203 Part 3
44
The Java Collections Framework 5
The remove method attempts to remove one instance of its
argument from the collection; if the argument occurs more
than once, other instances will be retained. The result
indicates whether an instance was found and removed.
The removeAll method will remove all instances of all of the
elements contained in the argument; true will be returned if
at least one element has been removed.
The retainAll method will remove all elements that are not
contained in the argument; true will be returned if at least
one element has been removed.
Autumn 2016
CE203 Part 3
45
The Java Collections Framework 6
The toArray methods return an array containing all of the
elements of the collection; duplicate elements in the collection
will occur more than once in the array, so the number of items
in the array will be equal to the size of the collection.
The version without an argument will always return a new
array of type Object[]. The other version allows existing
arrays to be reused by attempting to store the elements of the
collection in the array supplied as an argument. If this array is
too small a new array of the same type as the argument will be
created.
An exception of type ArrayStoreException may be thrown
if any of the elements cannot be stored in the array due to a
type mismatch.
Autumn 2016
CE203 Part 3
46
The Java Collections Framework 7
The behaviour of the equals method depends on the kind of
collections being compared – two sets are equal if they
contain the same elements but two lists are equal only if they
contain the same elements in the same order. The result will
always be false if an attempt is made to compare two
collection objects of different types, even if they contain the
same elements.
[ The hashCode and iterator methods will be explained
later. ]
Autumn 2016
CE203 Part 3
47
The Java Collections Framework 8
A simple program fragment demonstrating the use of methods
from the Collection interface is presented on the next slide.
We have to select a particular class that implements the
interface.
Note that the elements of collections are objects – when we
use the int variable i as an argument to a method from the
Collection interface a new Integer object containing the
value i is implicitly created.
If we were to modify this program fragment to use, for
example, Vector instead of TreeSet the behaviour would be
different since vectors may contain duplicate elements
whereas sets may not.
Autumn 2016
CE203 Part 3
48
The Java Collections Framework 9
Collection col = new TreeSet();
col.add(4);
int i;
for (i = 0; i < 6; i++)
{
if (col.add(i))
System.out.println("added “ +
else
System.out.println("could not
}
for (i = 2; i < 5; i++)
{
col.remove(i);
}
for (i = 0; i < 7; i++)
{
if (col.contains(i))
System.out.println("found “ +
else
System.out.println("could not
}
Autumn 2016
0
1
2
i);
3
add "+i);
4
5
i);
find “ + i);
CE203 Part 3
Added 0
Added 1
Added 2
Added 3
could not add 4
Added 5
found 0
found 1
could not find 2
could not find 3
could not find 4
found 5
could not find 6
49
The Java Collections Framework 10
We now provide a method that will remove from a collection of
objects of type String all strings whose length is greater than 10.
If the collection contains any non-strings an exception will be
thrown since downcasting will fail.
static void removeLongStrings(Collection c)
{
Object[] arr = c.toArray();
for (int i = 0; i<arr.length; i++)
{
String s = (String)arr[i];
if (s.length()>10)
c.remove(s);
}
}
Autumn 2016
CE203 Part 3
50
The Java Collections Framework 11
Note that if the collection contained two instances of the same
long string this string would appear twice in the array and
hence both instances would be removed.
The method is rather inefficient; having found a long string in
the array, the remove method when called will have to search
for it again in the collection. We could implement a much
more efficient version by moving through the collection an
item at a time, removing long strings as we find them. We
shall later see how to do this using an iterator.
Autumn 2016
CE203 Part 3
51
The Java Collections Framework 12
Take away messages
- Java collections framework provides a set of classes and
interfaces for holding multiple objects.
- These objects can be organized in a variety of ways for
different uses.
- We will now look at Vectors, as a useful member of the
collections framework.
Autumn 2016
CE203 Part 3
52
Vectors 1
The Vector class provides objects similar to arrays but whose size
can change. This class was provided in versions of the Java library
that pre-dated the introduction of the Collection interface, but
extra methods were added to it in subsequent versions to enable it
to implement the interface.
A vector has both a size and a capacity – the size refers to the
number of elements currently held in the vector whereas the
capacity refers to the amount of memory space currently allocated.
The initial capacity may be supplied as an argument to a
constructor when the vector is created.
Vectors are synchronized. This means they are thread safe and can
be safely used with only one thread, as opposed to arrayLists,
which are similar but not thread safe.
Autumn 2016
CE203 Part 3
53
Vectors 2
At any time the size of a vector must be less than or equal to
the capacity; if the addition of an element would cause the
size to become larger than the capacity the latter will be
increased.
To optimise use of space the capacity should be increased by a
small amount, but to optimise performance a larger increase
would be preferred, reducing the number of times the capacity
has to change. To allow the programmer to select a trade-off
between these two conflicting criteria, the amount by which
the capacity should be increased can be specified in a
constructor; if this has not been done the size will be doubled.
Autumn 2016
CE203 Part 3
54
Vectors 3
The capacity of a vector is never decreased automatically
when items are removed, but there is a method called
trimToSize that will reduce the capacity to the current size.
This would normally be used only if no more items are going
to be added to the vector or the capacity has become much
larger than the size.
In addition to the size method specified in the Collection
interface the Vector class has a method called capacity that
returns the current capacity.
Autumn 2016
CE203 Part 3
55
Vectors 4
The Vector class has four constructors. The first has no
arguments and sets the capacity to 10.
The second constructor takes an argument of type int and
uses that value for the initial capacity.
The third takes two arguments of type int, the first specifying
the initial capacity and then second the amount by which the
capacity should be increased when necessary.
All of these initialise the vector to be empty.
The fourth constructor takes an argument of type Collection
and copies the contents of the collection into the vector.
Autumn 2016
CE203 Part 3
56
Vectors 5
In order to permit a vector to be used like an array, methods
are provided to examine and replace the contents of a
particular location.
elementAt examines the contents (indexing starts from 0 as
with arrays).
An ArrayIndexOutOfBoundsException will be thrown if
the argument is out of range.
There are also methods called firstElement and
lastElement. These will throw an exception of type
NoSuchElementException if the vector is empty.
These exception types are subclasses of RunTimeException.
Autumn 2016
CE203 Part 3
57
Vectors 6
setElementAt = replace the contents of a specific location in
a vector.
This takes two arguments, a reference to an object and the
index of the location in which it is to be stored.
insertElementAt = shifts elements to make room for a new
one
removeElementAt = also shift the elements.
These methods may throw an exception of type
ArrayIndexOutOfBoundsException.
Autumn 2016
CE203 Part 3
58
Vectors 7
The add method, as specified in the Collection interface,
will append an element to the end of the vector and will
always return true.
The remove method will remove the first instance of the
element if there is more than one occurrence.
Autumn 2016
CE203 Part 3
59
Vectors 8
In addition to the contains method specified in the
Collection interface there is a method that will find the
location of an item if it is present in the vector. This method,
called indexOf, will return the location of the first
occurrence of its argument, or the value -1 if the argument is
not found in the vector.
There is also a lastIndexOf method, and two-argument
versions of both methods that start searching from a
particular location (specified by a second argument) instead
of from the beginning or end of the vector.
Autumn 2016
CE203 Part 3
60
Vectors 9
Here is a method to determine how many times an item occurs in a
vector.
public static int occurrences(Vector v, Object o)
{
int count = 0;
int pos = v.indexOf(o);
while (pos!=-1)
{
count++;
pos = v.indexOf(o, pos+1);
}
return count;
}
Autumn 2016
CE203 Part 3
61
Vectors 10
How does the Vector class differ from ArrayList?
In what context would you use Vector and when would you
use ArrayList?
Autumn 2016
CE203 Part 3
62
Quiz
kahoot.it
Autumn 2016
CE203 Part 3
63
Summary
• Today we covered
– Inheritance
– Abstract classes
– Interfaces
– Java collections framework
– Vectors
Autumn 2016
CE203 Part 3
64
Next week
•
•
•
•
Generics
More on interfaces
Iterators
Text fields
Autumn 2016
CE203 Part 3
65
Assignment 1
• Available on orb
(http://orb.essex.ac.uk/ce/ce203/syllabus.html)
• Deadline = Wednesday 9th November, 11:59:59
• 10% of module mark.
• Two exercises…
1) Write a GUI to display your name in different colours
2) Display an editable list of words in your GUI
Autumn 2016
CE203 Part 3
66