Four ways to describe the same computation
A paradigm is a style of organising a program — a view of what a program fundamentally is. The syllabus requires four, and the distinction that matters most is between saying how to do something and saying what you want.
Low-level programming works directly with the instruction set, giving complete control at the cost of readability. Imperative (procedural) programming gives an ordered sequence of statements that change state — the style of most introductory teaching. Object-oriented programming bundles data with the operations on it into objects. Declarative programming states the desired result and lets the system find it, which is what SQL does.
| Paradigm | Program is | Example | Suits |
|---|---|---|---|
| Low-level | machine instructions | assembly | drivers, embedded control |
| Imperative | a sequence of state changes | C, Python | general algorithms |
| Object-oriented | objects exchanging messages | Java, C++ | large systems, simulations |
| Declarative | a statement of the result | SQL, Prolog | queries, rule-based problems |
The how-versus-what distinction
An imperative program to find tall students would loop through a list, test each height and append matches to a result. A declarative one says SELECT name FROM student WHERE height > 180 and never mentions looping at all. Both produce the same answer; only the second leaves the method to the system. That is the cleanest way to separate the paradigms in an answer.
The object-oriented ideas that get examined
Object-oriented programming is built on a small number of ideas, and the marks go to those who can explain the purpose of each rather than just define it.
Encapsulation keeps data and the methods that act on it together, with the data private so it can only be changed through methods that enforce the rules. Inheritance lets a subclass take on the members of a superclass, so shared behaviour is written once. Polymorphism lets the same method call behave differently depending on the object receiving it.
- PRIVATE
- encapsulationreachable only through the class's own methods
- INHERITS
- inheritancethe subclass gains the superclass members
- overriding
- polymorphismthe same call resolves to different code
Say why, not just what
A definition of encapsulation earns one mark; the reason earns the second. Private data cannot be set to an invalid value by unrelated code, because every change must pass through a method that can check it — so the object is always in a valid state. The same applies to inheritance: the point is that shared code is written once, so a fix applies everywhere.
When things go wrong at run time
Some failures cannot be prevented by careful coding, because they depend on circumstances outside the program: a missing file, a full disk, a user typing letters into a number field, a division by a value that happened to be zero.
Exception handling separates the normal path from the error path. The risky code goes in a try block; if something fails, control jumps to a catch block that deals with it, and a finally block runs either way — which is where files get closed regardless of what happened.
The advantage over checking every operation with an if is that the normal logic stays readable, and an error can be handled at a sensible level rather than at the exact line where it occurred.
- TRY
- the risky codethe normal path, kept readable
- CATCH
- the handlerone per kind of exception you can deal with
- FINALLY
- cleanupruns either way — closing files, releasing resources
Good practice examiners look for
- Catch specific exceptions rather than everything indiscriminately.
- Never leave a catch block empty — a silently swallowed error is worse than a crash.
- Use
finallyto release resources, so files close even when something failed. - Validate input first; exceptions are for the unpredictable, not for ordinary checking.
- Report something useful to the user rather than exposing a raw system message.
- File processing is the classic case, because the file may be missing, locked or corrupt.
Why a large system is usually object-oriented
The paradigms are not merely a matter of taste, and questions often ask which suits a described project. The deciding factor is usually how large the program is and how many people maintain it.
A procedural program of a few hundred lines is perfectly clear. At a hundred thousand lines the difficulty is no longer the algorithms but keeping track of which parts of the code can affect which pieces of data. Object orientation addresses exactly that: making attributes private means a bug that corrupts an account balance must be inside the account class, rather than anywhere in the program.
Inheritance and polymorphism then allow new cases to be added without touching working code. A new subclass of Shape needs its own Area method, and every existing routine that calls Area continues to work unchanged — which is why the paradigm scales.
- Maintainability — a change to how data is stored affects only its own class.
- Reusability — a well-written class can be used by another program unaltered.
- Extensibility — new subclasses extend behaviour without editing existing code.
- Team working — different people can own different classes, meeting only at the interfaces.
- Modelling — objects map naturally onto real things, which suits simulations.
It is not free
Object orientation adds overhead — more code to write for a small task, a steeper learning curve, and a slight run-time cost for method calls and object creation. For a fifty-line script that reads a file and prints a total, a procedural program is genuinely the better engineering choice. A question asking you to justify a paradigm expects the trade-off, not an assertion that OOP is always superior.