Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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