Home Topic 4 Last Next

--- Thinking abstractly ---


Identify examples of abstraction.


Teaching Note:

Selecting the pieces of information that are relevant to solving the problem.

LINK Thinking ahead.


Sample Question:

From Sample Paper 1 2014:

Refer back to the question on 4.1.14.

JSR Notes:


Preface. The main take-away from this section on abstraction is that we can take a big program and divide it up into smaller parts, and by doing so, we can filter away of unnecessary information. This enables us to focus in on the one part or layer, which we want to understand and/or work on.


A General Definition of Abstraction:

Simply put, abstraction is the process of filtering out unnecessary information. (See the teaching note.)

In the process of programming, abstraction is basically representing something complex in a simpler way, ignoring details which are not necessary for the task at hand. This could be seen both in terms of things and in terms of solutions to problems, i.e. procedures.

- So with a complex system of things/data, we can group things/data into categories which are useful to us, given our task at hand, and filter out/ignore other parts of the system, or deeper levels of describing those things.

- Or in terms of a complex problem/procedural, we can "decompose" it into smaller problems and deal with each individual process on its own, disregarding the others for the time being.

Data Abstraction

General Example of Data Abstraction

A good example can be order made out of the complex system of people in the ISB community. We can bring order to this system both by decomposition so as to categorize, and also information hiding of details, to keep the overall understanding of the structure of the system comprehensible.

Representation of the people in the ISB community:

Example of Data

Decomposition via an OOP Hierarchy of Classes

Representation of sale items at a Saturday Market, using an OOP class hierarchy, which via decomposition, categorizes and organizes the sale items. Information hiding encapsulates all of the details of each class within itself.


Class Hierarchy:

The point with all this is that though it's overall a complex system, each individual class is focused in on itself, disregarding the other classes. For each individual class, how the other classes are implemented is of no concern them (with the exception of the class which it is connected to in the hierarchy).

package satrudaymarket;

public class MainForMarket {

    public static void main(String[] args) {
        Spinach[] spinaches = new Spinach[20];

        //blah blah blah


public class SaleItem {
    private int idNumber;

    public SaleItem(){


    //gets & sets and other methods


public class Fruit extends SaleItem{

    private double costPerKilo = 0.0;

    public Fruit(){


    //gets & sets and other methods



public class Apple extends Fruit {

    //attributes and methods specific for an Apple


public class Orange extends Fruit {

    //attributes and methods specific for an Apple



public class Vegetable {

    //attributes and methods specific for a Vegetable



public class Spinach extends Vegetable{
    private String name = "not set yet";
    private boolean isStrong = false;

    public Spinach(){


    public Spinach(String name, boolean isStrong){
        this.name = name;
        this.isStrong = isStrong;


Procedural Abstraction

General Example of Procedural Abstraction

Information hiding of associated procedures, in order to just understand one level/layer/part of a much more complex system/procedure. So just looking at one layer of abstraction; one procedure in and of itself, alone.

Example # 1: Making an apple pie. And just focusing in on the pie making/baking procedure itself

So in terms of filtering out unnecessary information, we don't have to worry ourselves about how the apples were grown and harvested, or how the oven works; we just need to focus on this one layer of abstraction, which is the simple steps listed above.


Example # 2: Organizing an IASAS Soccer Tournament

But how the schools pick their teams, the considerations coming up with the standard IASAS rules, or the certification of the officials, etc. are none of our concern; we can ignore those details, and rather focus on the tournament itself.



Important Abstraction Point

Later on in the middle of 4.3, a sub-section titled "Use of Programming Languages" the curriculum makes a really important point that actually isn't reinforced properly in one place, though it's the whole gist of modular programming - programming divided up into functions. So here's the point and I'm going to make it really really big, so that we make sure we acknowledge all these important "why" of abstraction, i.e. dividing a program up into classes and classes into functions:

Sub-programmes and objects support abstraction, which facilitates: ease of debugging and maintenance, reuse of code, modularity.

This - and the IB CS take on abstraction in general - focuses in more on the basics of dividing a big program up into classes, and dividing a class up into functions - rather than than the subtly different true meaning of abstraction which is filtering out unnecessary information. But that's OK at an introductory level, because it's the dividing a complex system up into classes and methods which allows the filtering away of everything else.

So even at this first introduction of the concept of abstraction, it is important to note these three things. And I'll paste this all again at then end of the official "abstraction" section of the curriculum. And again paste it some place after you fully appreciate how to make different classes, and different functions within them.

- Debugging is easier because you can comment out a function and re-run your code and if the bug goes away, you know part of the problem at least must be in that function. And by the same token you can run a multi-class program, and not use one of the classes, and if the problem no longer exists, you have isolated it to be associated with that class.

- Maintenance is easier, simply because you can work with small chunks of a program rather than working with the whole thing. You can focus in on one particular task and work with it, to greater and lesser extents, in isolation from the distraction of everything else.

- Reuse of Code is facilitated simply because you don't have to write the same code over and over again, rather, in the case of functions, you just call them by name, and in the case of classes (of the "template" kind), you can simply make new instances of them.

- Modularity - basically this is the same thing as abstraction, but by using functions and classes, you can move around them between programs and projects, similarly the way you can install various generic car parts on various models of cars.






Example of
Procedural Abstraction
Java Abstract Classes & Methods

Java included the ability to construct abstract classes, which can be used to suggest the basic outline of a particular method that could be used in a particular OOP hierarchy.

In the example below, there will be a calculateCosts( ) abstract method, which suggests how a method for calculating costs should work. And then, there will be particular calculateCosts( ) methods implemented in their own way in different classes - each hiding its particular implementation within the code of that particular class.

Note how each calculateCosts( ) method works independently of the other, and none is concerned with the details of the other one, in the other class. Each only focuses on the information relative to it's own problem, and filters out all other information. This is classic abstraction.

And in terms of Java implementation of this, you'll note that the calculateCosts( ) abstract method in the super class AllDomesticServices has no implementation at all; it is only an idea, a suggestion of what classes extending this class should do - which leads to the ability to use abstraction by specification (see below).

(Do note that this is not at all required in IB CS, but it's one actual great example of procedural abstraction in Java.)

package runningacountry;

public abstract class AllDomesticServices {

    public AllDomesticServices(){


    public abstract double calculateCosts(double [] servicesCosts);
    //An abstract method. So no implementation here. None needed here.
    //To be implemented by a class which extends this class, and 
    //adds its own particular details for how to calculate costs.


package runningacountry;

public class Infastructure extends AllDomesticServices{

    public double calculateCosts(double[] roadsAndHighwaysCosts) {
        double totalInfrastructureCost = 0;
        for(int i = 0; i < roadsAndHighwaysCosts.length; i++){
            totalInfrastructureCost+= roadsAndHighwaysCosts[i];
            boolean someOtherHighwayCondition = true;
        return totalInfrastructureCost;


package runningacountry;

public class UtilityResources extends AllDomesticServices {

    public double calculateCosts(double[] servicesCosts) {
        double totalServicesCosts = 0;
        for(int i = 0; i < servicesCosts.length; i++){
            totalServicesCosts+= servicesCosts[i];
            //And no other condition here. The point is that 
            //this calculateCosts works slightly differently than
            //the one for Infrastructure
        return totalServicesCosts;



Abstraction by Specification

(This is also beyond the scope of IB CS, but is good to know.)

It is good to note that since each of above procedural descriptions are fairly general - whether real life examples or programming examples - they can be applied to other similar situations. Baking a pie is basically the same approach as baking a cake. The steps to running and IASAS soccer tournament are generally the same as running an IASAS band festival. And calculate(ing)Costs( ) is similar from class to class; you take in an array of doubles, do something with it, and return a result.

So this is another advantage of abstraction. By keeping either a decomposition system fairly straight-forward, or keeping the concept of a certain procedure fairly-straight forward, we allow it to be applied in similar situations. In fact, we can simply re-use the model/procedure in slightly different contexts later one. And no only this, but within a project, or indeed within a company, there can be consistency with naming and return values/parameter lists for certain kinds of procedures and classes.