AbstractionHomepage  « Learn Java5 « Abstraction

In this lesson we continue our investigation of OO concepts by looking at abstraction. In the previous two lessons we looked at inheritance and how it enables us to avoid code duplication by setting a protocol for a group of classes. We used the extends keyword to subclass this common behaviour into more specific classes, whilst still being able to use the more abstract mechanics of the superclass. We set up an inheritance hierarchy to illustrate the mechanics of inheritance and how method invocation works. Something isn't right with our hierarchy though, so let's take a look at this:

abstract 1 abstract 2 abstract 3

When we last visited Vehicle Town, we had subclassed the Truck class, so our trucks could do more specific tasks. But in Vehicle town people are scared, there have been reports of strange vehicles and trucks roaming the streets. The mayor wants us to look into this and see whats going on.

We can create instances of Vehicle and Truck which makes no sense. What would these objects look like? They're just abstractions.

We can use the abstract keyword on the class so these objects cannot be instantiated but can still be extended.

Press the button below to cycle through our Vehicle Town problem.


Abstract Classesgo to top of page Top

In our class inheritance tree for Vehicle Town we need to stop instantiation of the Vehicle and Truck class, as these are abstractions for their subclasses. To do this we use the abstract keyword in the class definition. This means that the only static members of this class can ever be used unless we create a non-abstract subclass. So abstract classes need to be extended if we want to use any non-static members within the class. This also means that you can't declare a class as both abstract and final or the compiler complains. Non-abstract classes are known as concrete classes. Lets make our Vehicle class abstract.


/*
  A Vehicle Class
*/ 
public abstract class Vehicle { // Add the abstract keyword to the class definition

    ...

}

Save and compile our Vehicle class in directory   c:\_OOConcepts in the usual way.

We already have a TestVehicle class we coded earlier so lets rerun this.

run vehicle test class

The above screenshot shows the output of testing our abstracted Vehicle class. The compiler won't allow us to instantiate the Vehicle class which is exactly what we want.

Time to make our Truck class abstract as well.


/*
  A Truck Class
*/ 
public abstract class Truck { // Add the abstract keyword to the class definition

    ...

}

Save and compile our Truck class in directory   c:\_OOConcepts in the usual way.

We already have a TestTruck class we coded earlier so lets rerun this.

run truck test class

The above screenshot shows the output of testing our abstracted Truck class. The compiler won't allow us to instantiate the Truck class which is exactly what we want.

Abstract Methodsgo to top of page Top

We can also mark methods as abstract and if we do so the class must also be marked as abstract, as we can't have any abstraction in a concrete class. Whereas an abstract class must be extended in a subclass, an abstract method must be implemented in the first concrete subclass. This provides a contract that the compiler makes sure is met in the first concrete subclass. But why is this useful to us? Well it ensures that the first concrete subclass keeps to the contract by implementing any abstract methods of the superclass. To get to grips with this we need an example. We will code a new Truck subclass called Tanker.


/*
  A Tanker Class
*/ 
public class Tanker extends Truck {

}

Save and compile our Tanker subclass in directory   c:\_OOConcepts in the usual way.

Lets test the new Tanker subclass to make sure it works:


/*
  Test Class for Tanker
*/ 
public class TestTanker {

    public static void main (String[] args) {
        Tanker tanker = new Tanker();
        tanker.setChassis("8-axle chassis");
        tanker.setMotor("16 stroke");
        tanker.setWheels(10);
        System.out.println("Our Tanker has a " + tanker.getChassis() + ", " + tanker.getMotor() 
                                            + " motor and has " + tanker.getWheels() + " wheels.");
        tanker.service(3); 
        tanker.carry(2); 
        tanker.load("10,00 gallons of diesel"); 
    }
}

Save, compile and run the file in directory   c:\_OOConcepts in the usual way.

run Tanker class

The above screenshot shows the output of testing our Tanker subclass. If you look closely at the output we have a problem with the load() method, it is using the load() method from the Vehicle class. We don't really want this, we want our Tanker class to override the load() method like all subclasses of the Truck class do. So how to do this? Well we use method abstraction to ensure the first concrete subclass of our Truck class implements the abstracted method. To see this in action we will add an abstract load() method to our Truck abstract class:


/*
  A Truck Class
*/ 
public abstract class Truck extends Vehicle {
    /*
      Our carry() override method
    */ 
    public void carry(int tonnage) {
        System.out.println("Our truck can carry up to " + tonnage + " tons of cargo."); 
    }
    /*
      Our abstract load() method
    */ 
    public abstract void load(String payload); 
}

Well the code for our abstract load() method certainly looks different! Abstract methods have no body and are terminated by a semicolon.

Save and compile the file in directory   c:\_OOConcepts in the usual way.

We should rerun a subclass test to make sure everything is still hunky dory. So recompile Classes HGV and TestHGV and run the latter just to make sure everything still works:.

run HGV class

The above screenshot shows the output of testing our HGV subclass. The class still works as intended. For our purposes we have already overridden the load() method in the HGV subclass and thats what implementing an abstract method is, it's the same as overriding a method from a concrete superclass. This also means the same rules apply as those for overriding method rules

Lets see what happens if we don't implement an abstract method, by trying to recompile our new Tanker class:


/*
  A Tanker Class
*/ 
public class Tanker extends Truck {

}

Save and compile the file in directory   c:\_OOConcepts in the usual way.

run no imp Tanker class

As you can see from the screenshot we get a compiler error because we didn't implement the abstract load() method from the Truck superclass. Now we are assured that any concrete subclass of the Truck class implements the abstract load() method.

Abstraction Quizgo to top of page Top

Try the quiz below to test your knowledge of this lesson

Question 1 : What are non-abstract classes called?
- non-abstract classes are called <em>concrete</em> classes.
Question 2 : Abstract methods must be implemented in the first subclass?
- Abstract methods must be implemented in the first <em>concrete subclass</em>.
Question 3 : How do we instantiate an abstract class?
- We can't instantiate an <em>abstract</em> class.
Question 4 : What is unusual about an abstract method?
- An <em>abstract</em> method has no body.
Question 5 : What are the implications of putting an abstract method in a class?
- Putting an <em>abstract</em> method in a class makes the class <em>abstract</em>, which means the class must be declared as <em>abstract</em>.
Question 6 : Is the following code snippet valid?

public abstract class A { public abstract void load(); }

public abstract class B extends A { public abstract void load(String payload); }
- The code will compile fine but both of these methods would have to be implememnted in the first concrete subclass.
Question 7 : Is the following code snippet valid?

public abstract class A { public abstract void load(); }

public class B extends A { public abstract void load(); }
- The code will not compile as class B is not abstract and doesn't implememnt the abstract method from A.
Status Bar Please select an answer

What's Next?

In the next lesson we delve into polymorphism.

<<  Inheritance Concepts                    Polymorphism  >>

go to home page Java5 Tutor Homepage go to top of page Top