150 likes | 243 Views
Computer Science 209. Software Development Abstract Classes. Implementing a Stack Resource. <<Interface>> Iterable. Some behavior is provided by inheritance and some behavior is provided by composition. <<Interface>> Collection. <<Interface>> TrueStack. Abstract Collection.
E N D
Computer Science 209 Software Development Abstract Classes
Implementing a Stack Resource <<Interface>> Iterable Some behavior is provided by inheritance and some behavior is provided by composition <<Interface>> Collection <<Interface>> TrueStack Abstract Collection LinkedStack ArrayStack LinkedList ArrayList
Using the Stacks TrueStack<String> s1 = new ArrayStack<String>(); TrueStack<Integer> s2 = new LinkedStack<Integer>(); // . . . push a bunch of ints onto s2 for (int i : s2) s1.push(i + ""); TrueStack<String> s3 = new LinkedStack<String>(); s3.addAll(s1); The completed method addAll comes from AbstractCollection
Defining a Stack Interface import java.util.Collection; public interface TrueStack<E> extends Collection<E>{ public E pop(); public void push(E newElement); public E peek(); } <<Interface>> Iterable <<Interface>> Collection A Java interface can be compiled prior to developing any implementing classes <<Interface>> TrueStack
The Iterable Interface import java.util.Iterator; public interface Iterable<E>{ public Iterator<E> iterator(); } <<Interface>> Iterable <<Interface>> Collection Java automatically uses an iterator to generate code for a for-each loop All collections are required to implement the iterator method
The Collection Interface public interface Collection<E> extends Iterable<E>{ public boolean add(E newElement); public boolean addAll(Collection<E> col); public void clear(); public boolean contains(Object o); public boolean containsAll(Collection<E> col); public boolean isEmpty(); public boolean remove(Object o); public boolean removeAll(Collection<E> col); public boolean retainAll(Collection<E> col); public int size(); } <<Interface>> Iterable <<Interface>> Collection Methods in green must be included but need not be supported
Implementing a Stack Interface import java.util.*; public class ArrayStack<E> extends AbstractCollection<E> implements TrueStack<E>{ // As before } <<Interface>> Iterable <<Interface>> Collection <<Interface>> TrueStack Abstract Collection ArrayStack
The AbstractCollection Class • An abstract class serves as a repository of methods and/or data that are implemented in the same manner for any subclasses • Never instantiated, but always subclassed • Some methods are implemented, others remain abstract (to be implemented by subclasses)
The AbstractCollection Class abstract public class AbstractCollection<E> implements Collection<E>{ abstract public boolean add(E newElement); public boolean addAll(Collection<E> col){} public void clear(){} public boolean contains(Object o){} public boolean containsAll(Collection<E> col){} public boolean isEmpty(){} public boolean remove(Object o){} public boolean removeAll(Collection<E> col){} public boolean retainAll(Collection<E> col){} abstract public int size(); abstract public Iterator<E> iterator(); } abstract methods are completed in the subclasses
The AbstractCollection Class abstract public class AbstractCollection<E> implements Collection<E>{ public boolean contains(Object o){ for (E element : this) if (element.equals(o)) return true; return false; } public boolean containsAll(Collection<E> col){ for (E element : col) if (! this.contains(element)) return false; return true; } ... } Leverage the for-each loop and other methods!
The AbstractCollection Class abstract public class AbstractCollection<E> implements Collection<E>{ public boolean addAll(Collection<E> col){ boolean allAdded = true; for (E element : col) allAdded = allAdded && this.add(element); return allAdded; } public boolean isEmpty(){ return this.size() == 0; } ... } Methods that remove elements require the use of an explicit iterator – a topic for another day!
How Does This Work? abstract public class AbstractCollection<E> implements Collection<E>{ public boolean addAll(Collection<E> col){ for (E element : col) this.add(element); return true; } c1.addAll(c2); Java finds c1’s addAll method in its superclass, AbstractCollection Java then finds this’s add method in its original class, whatever that is Abstract Collection ASubclass
Dynamic Binding of Methods • The Java compiler can determine that the methods addAll and add are included in a given collection class (or its ancestors) • However, the implementation of the add method used in addAll cannot be determined until runtime, when the actual class of a collection is available
Interface or Abstract Class? • An interface contains only method headers, and specifies a set of abstract operations • An abstract class contains implemented methods and data for a set of subclasses, as well as abstract methods
Abstract Methods • An abstract method must be declared in an abstract class (and only there) when that method is used in other methods implemented in that class, but the implementation of the abstract method is deferred to subclasses • Examples: add and iterator