Skip to main content
SingaporeComputer ScienceSyllabus dot point

How does object-oriented programming model real things as classes and objects, and what do encapsulation and inheritance give us?

Define classes with attributes and methods, create objects, and apply encapsulation, inheritance and polymorphism in Python

A focused answer to the H2 Computing outcome on object-oriented programming. Classes and objects, attributes and methods, the constructor, and the principles of encapsulation, inheritance and polymorphism in Python.

Generated by Claude Opus 4.89 min answer

Reviewed by: AI editorial process; not yet individually human-reviewed

Have a quick question? Jump to the Q&A page

Jump to a section
  1. What this dot point is asking
  2. The answer
  3. Examples in context
  4. Try this

What this dot point is asking

SEAB wants you to define classes with attributes and methods, create objects from them, and apply the three core principles - encapsulation, inheritance and polymorphism - in Python. The central idea is that object-oriented programming bundles data and the operations on that data together into objects, so a program is modelled as interacting things rather than loose variables and functions.

The answer

Classes and objects

A class is a blueprint describing a kind of thing; an object is a specific instance of it. A class defines attributes (data) and methods (functions that act on that data):

class Dog:
    def __init__(self, name, age):   # constructor
        self.name = name             # attributes
        self.age = age

    def bark(self):                  # method
        return f"{self.name} says woof"

rex = Dog("Rex", 3)                  # an object (instance)
print(rex.bark())

The constructor __init__ runs when an object is created, initialising its attributes. self refers to the particular object the method is acting on.

Encapsulation

Encapsulation bundles data with the methods that use it and hides the internal data behind those methods. In Python a leading double underscore marks an attribute as private:

self.__balance = 0          # private; access only through methods

External code cannot change __balance directly; it must call methods that enforce the rules (a deposit must be positive, a withdrawal cannot overdraw). This keeps the object's data valid.

Inheritance

Inheritance lets a subclass acquire a parent class's attributes and methods, then add or override behaviour:

class Animal:
    def speak(self):
        return "..."

class Cat(Animal):           # Cat inherits from Animal
    def speak(self):         # override
        return "meow"

This reuses shared code in the parent and lets each subclass specialise. A new kind of animal is just a new subclass.

Polymorphism

Polymorphism lets objects of different classes be used through a common interface, each responding to the same call in its own way:

for animal in [Cat(), Dog("Rex", 3), Animal()]:
    print(animal.speak())   # the right version runs for each

The calling code does not need to know each object's exact type; it just calls speak() and the correct overridden method runs.

Examples in context

Example 1. A game with many entities. A game defines a Sprite parent with shared position and a draw() method, and subclasses Player, Enemy and Coin that override draw() and update(). The main loop iterates all sprites calling update() polymorphically, so adding a new entity type means adding one subclass, not editing the loop.

Example 2. A payroll system. An Employee class encapsulates pay details behind a calculate_pay() method; SalariedEmployee and HourlyEmployee subclasses override it with their own rules. Encapsulation guarantees pay is computed only through validated methods, and polymorphism lets the system total a mixed list of employees uniformly.

Try this

Q1. Distinguish between a class and an object. [2 marks]

  • Cue. A class is the blueprint defining attributes and methods; an object is a specific instance created from that class.

Q2. How does encapsulation protect an object's data? [2 marks]

  • Cue. It makes data private and accessible only through methods that enforce rules, so external code cannot set invalid values directly.

Q3. What does it mean to override a method in a subclass? [1 mark]

  • Cue. The subclass redefines an inherited method with its own version, which runs in place of the parent's for objects of that subclass.

Exam-style practice questions

Practice questions written in the style of SEAB exam questions on this dot point, with worked answer explainers. The year tag is the paper they imitate, not the source.

Original6 marksWrite a Python class `BankAccount` with a private balance, a constructor taking an opening balance, a `deposit(amount)` method and a `withdraw(amount)` method that refuses to overdraw. Explain how this demonstrates encapsulation.
Show worked answer →
class BankAccount:
    def __init__(self, opening):
        self.__balance = opening      # private attribute

    def deposit(self, amount):
        if amount > 0:
            self.__balance = self.__balance + amount

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance = self.__balance - amount
            return True
        return False                  # refuse to overdraw

    def get_balance(self):
        return self.__balance

This demonstrates encapsulation: the balance is a private attribute (__balance), so outside code cannot change it directly. All access goes through methods that enforce rules - deposits must be positive, withdrawals cannot exceed the balance. The object protects its own data and guarantees it stays valid.

Markers reward a constructor setting a private attribute, deposit and guarded withdraw methods, and the explanation that encapsulation hides data behind methods that enforce validity.

Original5 marks(a) Define inheritance and polymorphism. (b) A `Shape` class has a method `area()`. Explain how a `Circle` subclass and a `Rectangle` subclass use inheritance and polymorphism. (c) State one benefit of inheritance.
Show worked answer →

(a) Inheritance lets a subclass acquire the attributes and methods of a parent class, optionally adding or overriding behaviour. Polymorphism lets objects of different classes be treated through a common interface, with each responding to the same method call in its own way.

(b) Circle and Rectangle inherit from Shape, so they are both shapes. Each overrides area() with its own formula. Polymorphism means a list of mixed Shape objects can be looped over calling area() on each, and the correct version runs for each object's actual type, without the calling code knowing which shape it is.

(c) A benefit of inheritance is code reuse - shared behaviour is written once in the parent and inherited by all subclasses - and easier extension, since a new shape just adds a subclass.

Markers reward correct definitions, the subclasses overriding area() and being used through the common Shape interface, and a benefit such as code reuse.

Related dot points