Abstract Classes

In example in the previous section, both the ArraySet and ArrayList implementations had the same fields and the same print method. However, their add methods were different.

Thus it makes sense to define the fields and print methods in a parent class, but to not implement the add method yet.

An abstract class is halfway between a parent class and an interface. Abstract classes can declare fields, and they can also contain completed methods. However, they must contain at least one unimplemented method (like the method header in an interface). An unimplemented method is called an abstract method.

Declaring an abstract class

An abstract class is declared with the keyword abstract:

public abstract class Name 
{

}

Any abstract methods must also be declared with the keyword abstract:

visibility abstract returnType name(args);

Here is ArrayCollection rewritten as an abstract class:

public abstract class ArrayCollection 
{
    protected Object[] arr;
    protected int size; //we can declare fields

    //We don’t know how we're storing elements
    //So we don't know how to add yet
    public abstract void add(Object num);

    //We already know how to implement print()
    public void print() 
    {
        for (int i = 0; i < size; i++) 
        {
            System.out.println(arr[i].toString());
        }
    }
}

Note that we can now declare fields (arr, size) and have implemented methods (print()). However, the class is abstract because the add method is not implemented. This class represents an array of general object elements, but we don’t yet know how to implement the collection. We know that we would like an add operation, but don’t know how to write the code for it.

Extending an abstract class

Extending an abstract class is exactly like extending an ordinary class:

public class ChildName extends ParentName 
{

}

The only difference is that this class must implement every abstract method from the parent class.

Here is how we can implement the abstract class ArrayCollection by allowing duplicates:

public class ArrayList extends ArrayCollection
{
    //We inherit size and arr

    public ArrayList(int max) 
    {
        arr = new int[max];
        size = 0;
    }

    //add is no longer abstract
    public void add(Object elem)
    {
        if (size == arr.length) return;
        arr[size] = elem;
        size++;
    }

    //We inherit print()
}

Here are some examples of using the ArrayList class:

ArrayList ac = new ArrayList(10);
//ArrayList extends ArrayCollection
ArrayCollection c = new ArrayList(5);
ac.add(1);
ac.add(2);
c.add("a");
c.add("b");
c.add("c");
ac.print(); //ArrayList inherits print(), prints 1, 2
c.print(); //prints a, b, c