# Object-oriented problem solving

> CIE A-Level Computer Science · 9618
> Source: https://www.owlsprep.com/study/cie-9618-u13-object-oriented-problem-solving/

This module covers core principles of object-oriented (OO) problem solving for CIE 9618. You will learn to decompose real-world problems by identifying classes, objects, attributes, methods and model relationships between system entities.

**Prerequisites:** [Basic problem decomposition](https://www.owlsprep.com/study/cie-9618-u13-problem-decomposition/); [Fundamental programming concepts](https://www.owlsprep.com/study/cie-9618-u02-fundamental-programming/)

## Learning objectives

- Decompose real-world problems using core object-oriented principles
- Identify classes, attributes and methods from natural language problem descriptions
- Model correct relationships between classes (inheritance, aggregation)
- Apply encapsulation principles to robust OO problem designs

## Core OO Principles for Problem Decomposition

Object-oriented problem solving structures solutions around entities rather than standalone functions. This makes large, complex problems easier to maintain and extend, because changes to one part of the system have minimal impact on other parts.

**Object-oriented problem solving** — A problem-solving methodology that structures a solution around reusable entities (objects) that combine data (state) and behaviour (methods), rather than around standalone functions or procedures.

> **tip**
>
> OO problem solving is a design step completed before writing any code, it is not just a programming language feature.

**Worked example:** Decompose a simple school attendance system using OO principles. Name at least three core classes.

1. First, list all key tangible or conceptual entities the system needs to track.
2. Four core entities for an attendance system are: Student, Teacher, Session, and AttendanceRecord.
3. For each entity, identify stored data (attributes) and actions (methods):
4. - **Student**: attributes = `studentID`, `name`, `yearGroup`; methods = `registerAttendance()`, `getDetails()`
- **Session**: attributes = `sessionID`, `date`, `room`; methods = `startSession()`, `endSession()`
- **AttendanceRecord**: attributes = `recordID`, `isPresent`; methods = `updateStatus()`
5. Each entity maps to a class, and specific entries (e.g. student ID 12345) become objects of the corresponding class.

## Identifying Classes, Attributes and Methods

The first practical step in OO problem solving is extracting components from a natural language problem description. A simple rule of thumb is that nouns usually correspond to classes or attributes, while verbs usually correspond to methods.

> **mnemonic**
>
> Nouns are classes/attributes, verbs are methods! This quick rule helps you extract OO components from any problem description.

**Worked example:** Extract classes, attributes and methods from this description: 'A coffee shop needs a system to track orders. Each order has a date, a list of items, and a total price. Orders can calculate tax and print a receipt.'

1. Highlight all nouns: coffee shop, system, order, date, list of items, total price, tax, receipt.
2. Filter to core classes: only `Order` is a top-level core entity here; the other nouns are not standalone classes.
3. Assign remaining nouns as attributes of the `Order` class: `date`, `itemList`, `totalPrice`.
4. Highlight all verbs: track, has, calculate, print. Filter to methods: `calculateTax()` and `printReceipt()` are methods of `Order`.

**Check your understanding**

Test your understanding:

1. Which of the following is a method for a `BankAccount` class?

   - accountNumber
   - customerName
   - withdrawFunds
   - balance

   *Answer:* withdrawFunds

   *Why:* Correct: `withdrawFunds` is an action (verb) performed by a BankAccount. All other options are stored data (attributes).

## Modelling Relationships Between Classes

After identifying individual classes, you need to model how classes interact and relate to each other. The most common relationships used in OO problem solving are inheritance (is-a), aggregation (has-a whole-part) and association.

**Inheritance** — An 'is-a' relationship where a subclass inherits attributes and methods from a superclass, enabling code reuse and hierarchical classification.

*Example:* A `SavingsAccount` is a type of `BankAccount`, so `SavingsAccount` inherits from `BankAccount`.

**Worked example:** Model the inheritance hierarchy for a vehicle rental system, where the system rents cars, motorbikes and vans. All vehicles have a registration number, make and model, and can be hired or returned.

1. Identify the common superclass: all entities are vehicles, so create a top-level `Vehicle` class.
2. Move all common attributes and methods to the superclass: `Vehicle` has attributes `registrationNumber`, `make`, `model`, and methods `hire()`, `returnVehicle()`.
3. Create subclasses for each specific vehicle type, adding any unique attributes or methods:
4. - `Car`: adds `numberOfSeats` attribute and `calculateInsuranceCost()` method
- `Motorbike`: adds `engineCapacity` attribute
- `Van`: adds `cargoCapacity` attribute
5. This hierarchy avoids repeating code across classes, following core OO design principles.

## Encapsulation in OO Problem Design

Encapsulation is a core OO principle that supports robust problem design. It hides the internal implementation details of a class, only exposing a controlled public interface for interacting with objects.

> **info**
>
> Encapsulation prevents external code from modifying internal data directly, reducing unexpected bugs and making designs easier to maintain.

**Worked example:** Apply encapsulation to the `BankAccount` class, which stores a balance that should only be modified by approved deposits and withdrawals.

1. Make the `balance` attribute private, so it cannot be accessed or changed directly from outside the `BankAccount` class.
2. Create public methods to interact with the balance: `deposit(amount)`, `withdraw(amount)`, and `getBalance()` to view the current balance.
3. Add validation logic inside the public methods: `withdraw(amount)` can reject transactions where the amount exceeds the current balance, preventing negative balances.
4. External code can only change the balance via approved methods, so the class always maintains internal consistency.

## Common pitfalls

- **Wrong:** Turning every noun in the problem description into a separate class.
  - Why it fails: This leads to unnecessary classes and an overly complex, hard-to-implement design.
  - Correct: Filter nouns to only core entities with both attributes and behaviours; combine trivial nouns into attributes of larger classes.
- **Wrong:** Using inheritance for 'has-a' whole-part relationships.
  - Why it fails: For example, making `Wheel` a subclass of `Car` is incorrect, because a wheel is not a type of car.
  - Correct: Use inheritance for 'is-a' relationships only, use aggregation for 'has-a' whole-part relationships.
- **Wrong:** Making all attributes public, breaking encapsulation.
  - Why it fails: This allows uncontrolled modification of internal object state, leading to hard-to-trace bugs.
  - Correct: Make all attributes private by default, only expose public methods for controlled interaction with objects.
- **Wrong:** Putting all functionality into one large master class.
  - Why it fails: This violates the single responsibility principle, making the design hard to test, extend and maintain.
  - Correct: Split functionality across multiple classes, each responsible for one specific part of the problem.
- **Wrong:** Skipping OO design and jumping straight to writing code.
  - Why it fails: This leads to messy, ad-hoc designs that are hard to debug and do not meet exam marking criteria.
  - Correct: Always complete OO decomposition and class design before writing any code for your solution.

## Cheatsheet

| Component | How to Identify | Example |
| --- | --- | --- |
| Class | Core noun/entity in problem domain | Order |
| Attribute | Noun, property of a class | orderDate |
| Method | Verb, action performed by a class | calculateTax() |
| Inheritance | 'is-a' hierarchical relationship | SavingsAccount IS A BankAccount |
| Aggregation | 'has-a' whole-part relationship | Order HAS Item objects |
| Encapsulation | Hide internal data, expose methods | Private balance + public withdraw() |

## What's next

Mastering object-oriented problem solving is the foundation for designing all large-scale software systems, and is a regularly assessed topic for CIE 9618 Paper 1. The principles you learn here will be applied when you create standard UML class diagrams, write object-oriented code for practical tasks, and design software for your course practical assessment. This approach to problem solving also translates directly to industry software development, making it a valuable skill beyond your A-Level exam. Next, you will build on this core knowledge by exploring how to model OO system relationships and implement OO concepts in working code for assessment.

- [Declarative problem solving](https://www.owlsprep.com/study/cie-9618-u13-declarative-problem-solving/)
- [Artificial intelligence fundamentals](https://www.owlsprep.com/study/cie-9618-u13-artificial-intelligence-fundamentals/)
- [AI search techniques](https://www.owlsprep.com/study/cie-9618-u13-ai-search-techniques/)

---

From [OwlsPrep](https://www.owlsprep.com) — free study guides for A-Level, IB, AP and IGCSE, written against the official syllabus. Canonical page: https://www.owlsprep.com/study/cie-9618-u13-object-oriented-problem-solving/
