Presentation is loading. Please wait.

Presentation is loading. Please wait.

CE203 - Application Programming Autumn 2013CE203 Part 31 Part 3.

Similar presentations


Presentation on theme: "CE203 - Application Programming Autumn 2013CE203 Part 31 Part 3."— Presentation transcript:

1 CE203 - Application Programming Autumn 2013CE203 Part 31 Part 3

2 Autumn 2013CE203 Part 32 Inheritance 1 Suppose we have written a class Person to store information about persons (such as name and date of birth) and 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 we should implement the class Student as 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.

3 Autumn 2013CE203 Part 33 Inheritance 2 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 ; } }

4 Autumn 2013CE203 Part 34 Inheritance 3 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.

5 Autumn 2013CE203 Part 35 Inheritance 4 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(23,1,1981), 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.

6 Autumn 2013CE203 Part 36 Inheritance 5 In order 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 that 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.

7 Autumn 2013CE203 Part 37 Inheritance 6 Since a student is a person we may of course store students in an array of objects of type Person. 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.

8 Autumn 2013CE203 Part 38 Inheritance 7 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.

9 Autumn 2013CE203 Part 39 Inheritance 8 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); ……

10 Autumn 2013CE203 Part 310 Inheritance 9 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.

11 Autumn 2013CE203 Part 311 Inheritance 10 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]; }

12 Autumn 2013CE203 Part 312 Inheritance 11 The method on the previous slide will work if the element- types of the two arrays passed as arguments are the same and also if 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.

13 Autumn 2013CE203 Part 313 Abstract Classes 1 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; }

14 Autumn 2013CE203 Part 314 Abstract Classes 2 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); } }

15 Autumn 2013CE203 Part 315 Abstract Classes 3 Assume that we also have 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.

16 Autumn 2013CE203 Part 316 Abstract Classes 4 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 should place the attributes and methods that are common to all shapes in the Shape class, as seen on the next slide.

17 Autumn 2013CE203 Part 317 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; } }

18 Autumn 2013CE203 Part 318 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 }

19 Autumn 2013CE203 Part 319 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 Shape class 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.

20 Autumn 2013CE203 Part 320 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.

21 Autumn 2013CE203 Part 321 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

22 Autumn 2013CE203 Part 322 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

23 Autumn 2013CE203 Part 323 Comparing Objects 1 Suppose we have a Date class such as the one seen previously 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,2013); 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.

24 Autumn 2013CE203 Part 324 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.

25 Autumn 2013CE203 Part 325 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; }

26 Autumn 2013CE203 Part 326 The Java Collections Framework 1 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.

27 Autumn 2013CE203 Part 327 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();

28 Autumn 2013CE203 Part 328 The Java Collections Framework 3 public boolean remove(Object o); public boolean removeAll(Collection c); public boolean retainAll(Collection c); public Object[] toArray(); public Object[] toArray(Object[] a); public Iterator iterator(); public int hashCode(); public boolean equals(Object o); }

29 Autumn 2013CE203 Part 329 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.

30 Autumn 2013CE203 Part 330 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.

31 Autumn 2013CE203 Part 331 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.

32 Autumn 2013CE203 Part 332 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. ]

33 Autumn 2013CE203 Part 333 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.

34 Autumn 2013CE203 Part 334 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 "+i); else System.out.println("could not add "+i); for (i = 2; i<5; i++) col.remove(i); for (i = 0; i<7; i++) if (col.contains(i)) System.out.println("found "+i); else System.out.println("could not find "+i);

35 Autumn 2013CE203 Part 335 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 10) c.remove(s); } }

36 Autumn 2013CE203 Part 336 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.

37 Autumn 2013CE203 Part 337 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.

38 Autumn 2013CE203 Part 338 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.

39 Autumn 2013CE203 Part 339 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.

40 Autumn 2013CE203 Part 340 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.

41 Autumn 2013CE203 Part 341 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. The elementAt method is used to examine 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.

42 Autumn 2013CE203 Part 342 Vectors 6 To replace the contents of a specific location in a vector the setElementAt method can be used. This takes two arguments, a reference to an object and the index of the location in which it is to be stored. There is also a method called insertElementAt that shifts elements to make room for a new one and a method called removeElementAt which will also shift the elements. These methods may throw an exception of type ArrayIndexOutOfBoundsException.

43 Autumn 2013CE203 Part 343 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.

44 Autumn 2013CE203 Part 344 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.

45 Autumn 2013CE203 Part 345 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; }

46 Autumn 2013CE203 Part 346 Vectors 10 How does the Vector class differ from ArrayList ? In what context would you use Vector and when would you use ArrayList ?

47 Autumn 2013CE203 Part 347 Generics / Parameterised Types As a consequence of the introduction of generics in Java 5.0 collection classes and interfaces may now be parameterised by types, e.g. Collection. If a type parameter is provided the argument and result types of the methods will be more specific than Object, so, for example, for an object of type Vector the add method would expect an argument of type Date and the elementAt method would return a Date object.

48 Autumn 2013CE203 Part 348 The Set Interface The Set interface extends the Collection interface, but adds no extra definitions: public interface Set extends Collection {} Classes that implement this interface must therefore provide all of the methods specified in the Collection interface and should exhibit the expected properties of sets (e.g. no duplicate elements are allowed, two sets with the same elements are equal). The collections framework provides two classes that implement the interface, HashSet and TreeSet.

49 Autumn 2013CE203 Part 349 Iterators 1 Iterators can be used to access the contents of a collection one-by-one. An iterator may be thought of as a sequence of elements, together with a place-marker that lies between adjacent elements in this sequence. The sequence comprises all of the elements in the collection; for a hash set the order in which the elements occur in the sequence is unspecified, for a list or vector the elements will appear in the same order as in the collection.

50 Autumn 2013CE203 Part 350 Iterators 2 The iterator method specified in the Collection interface will return an iterator for the collection to which it is applied; the place-marker will be in front of the first element of the sequence. The iterator will implement the Iterator interface, which specifies three methods: public interface Iterator { public boolean hasNext(); public Object next(); public void remove(); }

51 Autumn 2013CE203 Part 351 Iterators 3 The hasNext method can be used to determine whether there are any more elements in the sequence after the place-marker; a loop to process the contents of a collection will generally take the form while (it.hasNext()) // do something with it.next() The next method returns a reference to the next item in the sequence and also advances the place-marker past that item; an exception of type NoSuchElementException will be thrown if the place-marker is at the end of the sequence.

52 Autumn 2013CE203 Part 352 Iterators 4 We could use the following method to print all of the items in a collection, one item per line: public static void print(Collection c) { Iterator it = c.iterator(); while (it.hasNext()) System.out.println(it.next()); }

53 Autumn 2013CE203 Part 353 Iterators 5 The following method will print all of the strings in a collection, but not any other items: public static void printStrings(Collection c) { Iterator it = c.iterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof String) System.out.println(o); } } Note that in order to visit all of the elements we must ensure that next is called only once in the loop body.

54 Autumn 2013CE203 Part 354 Iterators 6 If a collection is parameterised by a type its iterator will also be parameterised by that type and the next method will return an object of that type. The following method will calculate and return the total length of the items in a collection of strings. public static int totalLength( Collection c) { Iterator it = c.iterator(); int tot = 0; while (it.hasNext()) tot += it.next().length(); return tot; }

55 Autumn 2013CE203 Part 355 Iterators 7 An iterator can be used only for a single traversal of the sequence of elements so if we wish to traverse them again it is necessary to obtain a new iterator. The method on the next slide will print all the even integers in a collection of integers and subsequently print all of the odd integers. Note that we apply the intValue method to an Integer object when we need to retrieve the value stored in the object as an int. Also recall that the % operator is the modulo or remainder operator – a%b gives the remainder that would be obtained when dividing a by b.

56 Autumn 2013CE203 Part 356 Iterators 8 public static void printEvenThenOdd( Collection c) { Iterator it = c.iterator(); while (it.hasNext()) { Integer i = it.next(); if (i.intValue()%2==0) System.out.println(i); } it = c.iterator(); while (it.hasNext()) { Integer i = it.next(); if (i.intValue()%2!=0) System.out.println(i); } }

57 Autumn 2013CE203 Part 357 Iterators 9 If the objects in a collection have methods that allow them to be modified such methods can be applied. Assuming that a class called Employee has methods salary and setSalary we could apply the following method to increase the salary of each member of a collection of employees. public static void increaseSalary( Collection c) { Iterator it = c.iterator(); while (it.hasNext()) { Employee e = it.next(); e.setSalary(e.salary()+500); } }

58 Autumn 2013CE203 Part 358 Iterators 10 Methods that change the contents of an object in a set should be used with great care – they can have unpredictable effects if used inappropriately. For example a change to an element could result in duplicate elements. Additionally a change to an element in a hash set could change the hash value of that element, in which case subsequent searches might behave incorrectly. These problems do not occur with vectors and other types of list so methods that change the contents of objects in these types of collection may be freely used.

59 Autumn 2013CE203 Part 359 Iterators 11 In Java 5.0 a new form of for loop (known as the enhanced for statement) has been introduced, which allows the programmer to iterate through the contents of a collection without having to explicitly declare an iterator. The statement for (T x:c) …… serves as a shorthand notation for Iterator it = c.iterator(); while (it.hasNext()) { T x = it.next(); …… }

60 Autumn 2013CE203 Part 360 Iterators 12 We can rewrite the increaseSalary method using an enhanced for statement: public static void increaseSalary( Collection c) { for (Employee e:c) e.setSalary(e.salary()+500); } The introduction of the enhanced for statement does not eliminate the need to be able to understand and use iterators; if we wish to use the remove method from the Iterator interface we must explicitly obtain an iterator for the collection.

61 Autumn 2013CE203 Part 361 Iterators 13 The remove method from the Iterator interface can be used to remove items from a collection. When applied to the iterator it will remove from the collection the object returned by the most recent call to next. This method will throw an IllegalStateException if next has not been called, and also if remove is called twice without a call to next between the two calls. We could use the method on the following slide to remove all non-students from a collection of objects of type Person. (We assume, as in earlier examples, that Student is a subclass of Person.)

62 Autumn 2013CE203 Part 362 Iterators 14 public static void removeNonStudents( Collection c) { Iterator it = c.iterator(); while (it.hasNext()) if (!(it.next() instanceof Student)) it.remove(); }


Download ppt "CE203 - Application Programming Autumn 2013CE203 Part 31 Part 3."

Similar presentations


Ads by Google