Computer Science  ·  Level 6
Fundamentals Of Programming

Chapter 6: Object Oriented Programming

📚 4 Topics
⚑ What you will be able to do

By the end of this chapter, you will be able to:

  • apply object-oriented programming principles confidently in your projects.
  • create and use classes correctly to organize your code.
  • implement objects based on classes to represent real-world things clearly.
  • apply inheritance to build meaningful relationships between classes.
  • develop programs that reuse and extend code effectively through inheritance.

Mastering these skills will help you write clean, efficient programs that solve real-world problems just like professional developers do!

6.1 Object oriented programming concepts

Object oriented programming organises a program around objects. An object keeps its data, called attributes, together with the methods that work on that data, and it is created from a class that describes it. Java programs for a repair shop, a helpdesk or a network inventory become easier to write and change when each real thing, such as a device, a ticket or a voucher, is a class of its own. Four concepts support this way of working: inheritance lets one class build on another, encapsulation protects the data inside a class, abstraction shows what an object does and hides how, and polymorphism lets the same call behave differently for different objects. The topics on classes and objects that follow show how to write and use them in detail; this topic explains the four concepts and demonstrates each with a program.

6.1.1 Inheritance

Inheritance lets a new class, the subclass, take over the attributes and methods of an existing class, the superclass, and then add its own. The keyword extends creates the link. Inheritance suits groups of things that share common features: laptops, phones and printers in a repair shop are all devices with a name and a power switch, so those shared features can be written once in a class Device. The test for a sound inheritance link is the phrase "is a": a Laptop is a Device, a Phone is a Device.

public class InheritanceDemo {
    public static void main(String[] args) {
        Laptop lap = new Laptop("Lap-01", 16);
        lap.powerOn();
        lap.showRam();

        Phone ph = new Phone("Ph-07");
        ph.powerOn();
        ph.makeCall("0700000000");
    }
}

class Device {
    protected String name;

    Device(String name) {
        this.name = name;
    }

    void powerOn() {
        System.out.println(name + " is on");
    }
}

class Laptop extends Device {
    private int ramGb;

    Laptop(String name, int ramGb) {
        super(name);
        this.ramGb = ramGb;
    }

    void showRam() {
        System.out.println(name + " has " + ramGb + " GB of RAM");
    }
}

class Phone extends Device {
    Phone(String name) {
        super(name);
    }

    void makeCall(String number) {
        System.out.println(name + " calls " + number);
    }
}

Output:

Lap-01 is on
Lap-01 has 16 GB of RAM
Ph-07 is on
Ph-07 calls 0700000000

Neither Laptop nor Phone declares name or powerOn, yet both objects use them, because they are inherited from Device. Each subclass adds only what is special to it: the RAM size for a laptop and the call feature for a phone.

Points to remember about inheritance in Java:

  • The super call: a constructor is not inherited. The first statement of a subclass constructor should be super(...), which runs the superclass constructor. If it is omitted, Java inserts super(), and the program does not compile when the superclass has no constructor without parameters.
  • Access to inherited members: a private member of the superclass exists inside the subclass object but cannot be used by name in the subclass. Use a protected member, as with name above, or a public getter.
  • One superclass only: a Java class can extend only one class. A class can still take on several types by implementing several interfaces, which are described under abstraction.
  • The root class: every class extends the class Object, directly or through other classes, so every object has methods such as toString and equals.
  • Stopping inheritance: a class declared final cannot be extended, and a method declared final cannot be overridden.

Inheritance reduces repeated code, and a correction made in the superclass reaches every subclass. The same link also means that a careless change to the superclass can break all of its subclasses, so a superclass should be small and stable.

6.1.2 Encapsulation

Encapsulation means keeping the attributes of a class private and allowing other classes to reach them only through public methods. The class then controls how its data changes. A battery pack in a diagnostic tool must report a charge between 0 and 100 per cent; if any part of the program could write the attribute directly, a value such as 150 could slip in, and every calculation that follows would be wrong.

public class EncapsulationDemo {
    public static void main(String[] args) {
        BatteryPack pack = new BatteryPack();
        pack.setCharge(80);
        pack.setCharge(150);
        System.out.println("Charge: " + pack.getCharge() + "%");
    }
}

class BatteryPack {
    private int charge;

    public int getCharge() {
        return charge;
    }

    public void setCharge(int charge) {
        if (charge >= 0 && charge <= 100) {
            this.charge = charge;
        } else {
            System.out.println("Rejected: charge must be from 0 to 100");
        }
    }
}

Output:

Rejected: charge must be from 0 to 100
Charge: 80%

The first call stores 80. The second is refused by the check inside setCharge, so the charge remains 80. If main tried to write pack.charge = 150;, the compiler would stop the program, because charge is private.

Benefits of encapsulation:

  • Validation: the setter can refuse impossible values, as in the program above.
  • Read-only data: an attribute with a getter and no setter cannot be changed from outside, for example a ticket number once it has been assigned.
  • Freedom to change: the inside of the class can be rewritten, for example to store the charge as a decimal, without changing the code that calls getCharge and setCharge.
  • Fewer errors: because only the class itself changes its attributes, a wrong value is traced to one place.
  • Controlled side effects: a setter can do extra work, such as logging a change or recalculating a related value.

The usual pattern is a private attribute, a public getter named getX (isX for a boolean) and, where change is allowed, a public setter named setX.

6.1.3 Abstraction

Abstraction means showing what an object can do and hiding how it does it. A user of a storage device needs to know its type and capacity, not how the data is physically recorded. In Java, abstraction is written with abstract classes and interfaces.

Abstract classes

An abstract class is declared with the keyword abstract and cannot be used to create objects. It can contain abstract methods, which have a header and no body, and ordinary methods, which are inherited as they are. Every concrete subclass must give a body to every abstract method.

public class AbstractionDemo {
    public static void main(String[] args) {
        StorageDevice[] devices = {new FlashDisk(32), new HardDisk(500)};
        for (StorageDevice d : devices) {
            d.describe();
        }
    }
}

abstract class StorageDevice {
    abstract String typeName();

    abstract int capacityGb();

    void describe() {
        System.out.println(typeName() + ": " + capacityGb() + " GB");
    }
}

class FlashDisk extends StorageDevice {
    private int gb;

    FlashDisk(int gb) {
        this.gb = gb;
    }

    String typeName() {
        return "Flash disk";
    }

    int capacityGb() {
        return gb;
    }
}

class HardDisk extends StorageDevice {
    private int gb;

    HardDisk(int gb) {
        this.gb = gb;
    }

    String typeName() {
        return "Hard disk";
    }

    int capacityGb() {
        return gb;
    }
}

Output:

Flash disk: 32 GB
Hard disk: 500 GB

The method describe is written once in the abstract class and relies on two methods whose details differ in each subclass. The statement new StorageDevice() would not compile, because an abstract class is only a pattern for its subclasses.

Interfaces

An interface lists methods that a class promises to provide, without saying how. Its methods are public and abstract unless they are declared default or static. A class that implements an interface must write a body for every abstract method of it, unless the class is itself abstract. A class can implement several interfaces, which is how Java allows one class to have more than one type.

public class InterfaceDemo {
    public static void main(String[] args) {
        Printable[] items = {new Invoice(1001), new Label("WS-01")};
        for (Printable p : items) {
            p.print();
        }
    }
}

interface Printable {
    void print();
}

class Invoice implements Printable {
    private int number;

    Invoice(int number) {
        this.number = number;
    }

    public void print() {
        System.out.println("Printing invoice " + number);
    }
}

class Label implements Printable {
    private String text;

    Label(String text) {
        this.text = text;
    }

    public void print() {
        System.out.println("Printing label " + text);
    }
}

Output:

Printing invoice 1001
Printing label WS-01

The loop in main knows only that each item is Printable. It does not know or need to know whether an item is an invoice or a label, so a new printable class can be added later without changing the loop. Choose an abstract class when related classes share attributes and ready-made methods; choose an interface when unrelated classes must offer the same ability.

6.1.4 Polymorphism

Polymorphism means "many forms": one method call can produce different behaviour depending on the object that receives it. Java has two kinds. Compile-time polymorphism is method overloading, where the compiler picks a version by looking at the arguments, as explained in Demonstration of methods. Run-time polymorphism is method overriding, where a subclass replaces an inherited method with its own version and Java chooses the version while the program is running, according to the actual type of the object.

public class PolymorphismDemo {
    public static void main(String[] args) {
        Notification[] queue = {
            new Notification(),
            new EmailNotification("customer@example.com"),
            new SmsNotification("0700000000")
        };
        for (Notification n : queue) {
            n.send("Your device is ready for collection");
        }
    }
}

class Notification {
    void send(String message) {
        System.out.println("Notice: " + message);
    }
}

class EmailNotification extends Notification {
    private String address;

    EmailNotification(String address) {
        this.address = address;
    }

    @Override
    void send(String message) {
        System.out.println("Email to " + address + ": " + message);
    }
}

class SmsNotification extends Notification {
    private String number;

    SmsNotification(String number) {
        this.number = number;
    }

    @Override
    void send(String message) {
        System.out.println("SMS to " + number + ": " + message);
    }
}

Output:

Notice: Your device is ready for collection
Email to customer@example.com: Your device is ready for collection
SMS to 0700000000: Your device is ready for collection

The array holds Notification references, yet each call n.send(...) runs the version that belongs to the real object: the plain notice, the email or the SMS. The loop does not test the type of each object, so adding a WhatsApp notification later means writing one new subclass and no change to the loop.

Rules for overriding:

  • Same signature: the overriding method has the same name and the same parameter types as the inherited one.
  • The override annotation: writing @Override makes the compiler report a mistake, for example a misspelt method name, instead of silently creating a new method.
  • Access may not shrink: an overriding method can be more visible than the original but not less, so a public method cannot be overridden as private.
  • Not everything is overridden: private, static and final methods are not overridden. Attributes are not polymorphic: a reference chooses the attribute by its declared type.
  • Calling the original: super.send(message) inside the overriding method runs the superclass version, which is useful when the new version only adds to the old one.
The rest of this chapter
🔒

Create a free account to open more of this chapter.

Free: practical guides, quick cards, workplace scenarios and more.

Create a free account
🔒6.2 Classes

A class is the blueprint from which objects are made. It describes what every object of that kind knows, through its attributes, and what every object of that kind can do, through its methods. A class for a helpdesk ticket, for example, says that every ticket…

🔒6.3 Objects

An object is one actual thing made from a class. The class Voucher describes what any Wi-Fi voucher holds; the objects are the individual vouchers, each with its own code and its own number of minutes. Objects are created while the program runs, and each one c…

🔒6.4 Creation of programs to implement inheritance

This topic builds a complete program in which inheritance does real work. The program bills the jobs of a small ICT workshop: a general job, a repair job that also charges for spare parts, and a network installation job that also charges for each network point…

Chapter Practical Activities

Practical 1: Define and Implement Classes and Objects for a Library System

Computer Science · Level 6
Fundamentals Of Programming
PRACTICAL ASSESSMENT
TIME: 4 HOURS
⬇ PDFCandidate Instructions (Candidate Tool)

Type: Individual

INSTRUCTIONS TO CANDIDATE:
1.  You are required to perform the following task:
i.  Define a class 'Book' with attributes and methods, then create and manipulate objects to display book details and availability status.
2.  You have been provided with the following resources for the practical task:
Tools & EquipmentMaterials
Functional computer installed with Java IDE (NetBeans/Eclipse/IntelliJ)Class attributes: bookID, title, author, isAvailable
Plain paperMethods: displayDetails(), borrowBook(), returnBook()
Pen
⬇ PDFResources Required (Cutting List)
S/NItemQuantity
1Functional computer installed with Java IDE (NetBeans/Eclipse/IntelliJ)1 Pc per Candidate
2Plain paper1 Pc per Candidate
3Pen1 Pc per Candidate
⬇ PDFAssessor Guide
Items to be EvaluatedMarks AvailableMarks ObtainedComments
TASK 1: Define Class and Attributes
Launched the Java IDE
(Award 2 marks or 0)
2
Declared class named 'Book'
(Award 2 marks or 0)
2
Declared attributes: bookID, title, author, isAvailable
(Award 1 mark for each attribute declared correctly)
4
Sub-Total8
TASK 2: Implement Methods
Declared method displayDetails() that prints all book attributes
(Award 3 marks or 0)
3
Declared method borrowBook() that sets isAvailable to false
(Award 3 marks or 0)
3
Declared method returnBook() that sets isAvailable to true
(Award 3 marks or 0)
3
Sub-Total9
TASK 3: Create and Manipulate Objects
Created at least two Book objects with initial values
(Award 3 marks or 0)
3
Called displayDetails() method on each object
(Award 3 marks or 0)
3
Called borrowBook() on one object and verified isAvailable status
(Award 3 marks or 0)
3
Called returnBook() on same object and verified isAvailable status
(Award 3 marks or 0)
3
Sub-Total12
PRODUCT CHECKLIST
Class Book correctly defined with all attributes and methods
(Award 6 marks or 0)
6
Objects created and methods function as expected with correct output
(Award 5 marks or 0)
5
Sub-Total11
GRAND TOTAL40
ASSESSMENT OUTCOME:   ☐ Competent    ☐ Not Yet Competent (competent if at least 50%)

Practical 2: Implement Encapsulation Using Access Modifiers in a Java Class

Computer Science · Level 6
Fundamentals Of Programming
PRACTICAL ASSESSMENT
TIME: 4 HOURS
⬇ PDFCandidate Instructions (Candidate Tool)

Type: Individual

INSTRUCTIONS TO CANDIDATE:
1.  You are required to perform the following task:
i.  Write a Java class named 'Student' with private attributes and public getter and setter methods for name (String), age (int), and grade (char).
2.  You have been provided with the following resources for the practical task:
Tools & EquipmentMaterials
Computer with Java IDE (Eclipse/NetBeans/IntelliJ)Plain A4 Paper
Pen
⬇ PDFResources Required (Cutting List)
S/NItemQuantity
1Computer with Java IDE (Eclipse/NetBeans/IntelliJ)1 Pc per Candidate
2Plain A4 Paper2 Pcs per Candidate
3Pen1 Pc per Candidate
⬇ PDFAssessor Guide
Items to be EvaluatedMarks AvailableMarks ObtainedComments
TASK 1: Class Declaration and Attributes
Launched Java IDE and created a new Java project
(Award 2 marks or zero)
2
Declared class named 'Student'
(Award 2 marks or zero)
2
Declared private attributes: name (String), age (int), grade (char)
(Award 2 marks for each correctly declared attribute)
6
Sub-Total10
TASK 2: Getter and Setter Methods Implementation
Declared public getter methods for all private attributes
(Award 2 marks for each correctly implemented getter method)
6
Declared public setter methods for all private attributes
(Award 2 marks for each correctly implemented setter method)
6
Setter methods include basic validation: age >= 0, grade is a valid char
(Award full 4 marks if validation is implemented correctly, else zero)
4
Sub-Total16
TASK 3: Testing and Display
Created a main method to instantiate the Student class object
(Award 2 marks or zero)
2
Used setter methods to assign values to attributes
(Award 1 mark for each attribute assigned correctly)
3
Used getter methods to display the attribute values
(Award 1 mark for each attribute displayed correctly)
3
Sub-Total8
PRODUCT CHECKLIST
Class 'Student' compiles without errors and encapsulation is correctly implemented
(Award 5 marks if code compiles and encapsulation is demonstrated)
5
Getter and setter methods correctly restrict direct access to private attributes
(Award 5 marks for proper use of access modifiers and method functionality)
5
Output shows correct attribute values retrieved via getter methods
(Award 5 marks if output matches assigned values)
5
Sub-Total15
GRAND TOTAL49
ASSESSMENT OUTCOME:   ☐ Competent    ☐ Not Yet Competent (competent if at least 50%)
🔒

Free: practical guides, quick cards, workplace scenarios and more.

Create a free account
🔒Implement a subclass demonstrating inheritance in JavaPractical 3
🔒Implement polymorphism using method overriding in JavaPractical 4
🔒Implement a Student Class with Constructors and DestructorsPractical 5
🔒Implement Interface and Abstract Class for Vehicle Management SystemPractical 6
🔒Demonstrate Association and Aggregation in Java ClassesPractical 7
🔒Implement Composition in Classes for a Library Management SystemPractical 8
🔒Implement a Java class using static variables and methods to track instance countPractical 9
🔒Implement Exception Handling in a Java Object-Oriented ProgramPractical 10
Am I competent?

At the start of this chapter we promised you would be able to:

  • apply object-oriented programming principles confidently in your projects.
  • create and use classes correctly to organize your code.
  • implement objects based on classes to represent real-world things clearly.
  • apply inheritance to build meaningful relationships between classes.
  • develop programs that reuse and extend code effectively through inheritance.

Tick each one you can genuinely do.

So, are you there yet?

You're competent when you can confidently do 50% or more of what this chapter promised.

Sign in to record how you're doing.