Show understanding of the characteristics of a number of programming paradigms: Object Oriented

20 Programming Paradigms

20.1 Object‑Oriented Programming (OOP)

What is the Object‑Oriented Paradigm?

OOP models a program as a collection of objects. Each object bundles:

  • State – data stored in instance variables (also called attributes).
  • Behaviour – operations expressed as methods (functions that belong to a class).

An object is created from a class, which defines the structure (variables) and capabilities (methods) that all its objects share.

Core OO Concepts (Cambridge terminology)

Concept Definition (syllabus wording) How it is realised in Python
Encapsulation Bundling of data and the methods that manipulate that data, with access control that hides the internal implementation. Prefix instance variables with an underscore (e.g. _balance) and provide public getter/setter methods. Python does not enforce strict access modifiers, but the convention signals “private”.
Inheritance Mechanism by which a new class (sub‑class) automatically acquires the attributes and methods of an existing class (super‑class). Define the subclass with the parent class in parentheses, e.g. class Car(Vehicle):. Use super().__init__(...) to initialise the super‑class.
Polymorphism Ability for a single interface to represent different underlying forms; the same method call can invoke different method bodies. Method overriding in a subclass (dynamic dispatch). Python also supports overloading through default arguments or *args/**kwargs.
Abstraction Providing a simplified model of a complex real‑world entity by exposing only essential features. Use abstract base classes from the abc module or define a class that only specifies method signatures (no implementation).

Typical OO Constructs – Python Example

class Vehicle:
    """Encapsulated state + basic behaviour for all vehicles."""
    def __init__(self, make: str, year: int):
        self._make = make          # “private” attribute
        self._year = year

    def start(self) -> None:
        print("Engine started")

    # accessor (getter)
    def get_make(self) -> str:
        return self._make


class Car(Vehicle):
    """Car inherits from Vehicle and overrides start()."""
    def __init__(self, make: str, year: int, doors: int):
        super().__init__(make, year)   # initialise Vehicle part
        self._doors = doors

    def start(self) -> None:           # polymorphic method
        print("Car ignition")

    def get_doors(self) -> int:
        return self._doors

Advantages of OOP (exam‑style bullet points)

  1. Improved modularity – each class can be developed, tested and debugged in isolation.
  2. Code reuse – inheritance and composition avoid duplication.
  3. Easier maintenance – changes to a class affect only its objects; polymorphic interfaces hide implementation changes.
  4. Closer mapping to real‑world concepts, aiding analysis and design.
  5. Supports design patterns that promote flexible, extensible systems.

Disadvantages / Limitations

  1. Risk of over‑engineering – deep inheritance trees can become fragile.
  2. Higher memory consumption because each object carries its own attribute dictionary.
  3. Steeper learning curve for abstraction, polymorphism and design patterns.
  4. Potential performance overhead (dynamic dispatch, indirection) compared with straight‑line procedural code, especially in tight loops.

Common OO Languages (Cambridge examples)

  • Java
  • C++
  • C#
  • Python (supports multiple paradigms but widely used OO)
  • Ruby

Key Points to Remember for the Exam

  • Define and give a short example of encapsulation, inheritance, polymorphism, abstraction.
  • Explain how OOP promotes modularity and code reuse.
  • Identify situations where OOP is less suitable (e.g., very memory‑constrained embedded systems, simple scripts).
  • Read and write a simple class definition; recognise OO concepts in a code fragment.
  • Distinguish between overriding (runtime polymorphism) and overloading (compile‑time polymorphism or default arguments in Python).

20.2 Procedural Programming

What is the Procedural Paradigm?

Procedural programming treats a program as a sequence of instructions grouped into procedures (also called functions or sub‑routines). Data and code are separate: variables are typically global or have block scope, and the flow of control is explicit (loops, conditionals, calls).

Key Characteristics

  • Top‑down design – the problem is broken into smaller tasks, each implemented as a procedure.
  • Single‑entry, single‑exit – each procedure has one entry point and returns control to the caller.
  • Variable scope – local variables are visible only inside the procedure; global variables are visible everywhere.
  • Reusability through functions – the same procedure can be called from many places.

Procedural Example (Python)

# reusable function
def max_of_two(a: int, b: int) -> int:
    return a if a > b else b

def main() -> None:
    x = 5
    y = 9
    greatest = max_of_two(x, y)   # call the procedure
    print(f"Greatest = {greatest}")

if __name__ == "__main__":
    main()

Advantages

  1. Simple mental model – linear flow of control is easy to follow.
  2. Low overhead – no object metadata, usually less memory use.
  3. Well suited to small utilities, system scripts, and performance‑critical sections.

Disadvantages

  1. Limited modularity – data is often shared globally, leading to tight coupling.
  2. Code duplication – similar functionality may be copied instead of reused via inheritance/composition.
  3. Harder to model real‑world entities that naturally have state and behaviour together.

Exam‑style Checklist

  • Identify a procedure/function and its parameters/return type.
  • Explain the difference between local and global variables.
  • Describe how a procedural program can be broken into modules (e.g., separate Python files imported with import).

20.3 Functional Programming

What is the Functional Paradigm?

Functional programming treats computation as the evaluation of pure functions. A pure function has no side‑effects and always returns the same result for the same arguments. Data is immutable, and functions are first‑class values – they can be passed as arguments, returned from other functions, and stored in variables.

Core Concepts (Cambridge terminology)

  • Pure functions – no modification of external state.
  • Immutability – once created, data values cannot be changed.
  • Higher‑order functions – functions that take other functions as parameters or return them.
  • Recursion – primary mechanism for repetition (instead of explicit loops).
  • Function composition – building complex behaviour by combining simpler functions.

Functional Example (Python)

# pure function – no side‑effects
def square(x: int) -> int:
    return x * x

# higher‑order function: map applies a function to every element
numbers = [1, 2, 3, 4]
squares = list(map(square, numbers))   # [1, 4, 9, 16]

# recursion example – factorial
def factorial(n: int) -> int:
    if n == 0:
        return 1
    return n * factorial(n - 1)

Advantages

  1. Facilitates reasoning – absence of side‑effects makes debugging easier.
  2. Naturally supports parallelism because immutable data cannot be corrupted by concurrent threads.
  3. Concise expression of operations on collections (map, filter, reduce).

Disadvantages

  1. Recursive solutions can lead to deep call stacks; tail‑call optimisation is not guaranteed in CPython.
  2. Learning curve for thinking in terms of functions rather than statements.
  3. Some algorithms are less intuitive without mutable state (e.g., in‑place sorting).

Exam‑style Checklist

  • Identify a pure function and explain why it has no side‑effects.
  • Write a simple recursive function and state the base case.
  • Give an example of a higher‑order function (e.g., map or filter).

20.4 Event‑Driven / Declarative Programming (Brief Overview)

Event‑Driven Programming

Execution is driven by events such as user actions, sensor input or messages. A program registers event handlers (callback functions) that are invoked when the corresponding event occurs.

import tkinter as tk

def on_click():
    print("Button pressed")

root = tk.Tk()
btn = tk.Button(root, text="Press me", command=on_click)
btn.pack()
root.mainloop()

Declarative Programming

Instead of specifying *how* to achieve a result, the programmer states *what* the result should be. Examples include SQL (what data to retrieve) and HTML/CSS (what a page should look like).

When are these paradigms preferred?

  • Graphical user interfaces, real‑time systems, and web applications – event‑driven.
  • Data‑query tasks, configuration files, and UI layout – declarative.

20.5 Comparison of the Four Paradigms

Aspect Object‑Oriented Procedural Functional Event‑Driven / Declarative
Primary abstraction Objects (state + behaviour) Procedures / functions Pure functions & immutable data Events & callbacks / statements of *what* to achieve
Data handling Encapsulated, access‑controlled Variables with global or block scope Immutable values Data supplied by external sources (e.g., UI events)
Reuse mechanism Inheritance, composition, interfaces Modular functions, libraries Higher‑order functions, function composition Reusable event handlers, declarative templates
Polymorphism Method overriding / overloading None (except via function pointers) Function composition, first‑class functions Multiple handlers can respond to the same event type
Typical use‑cases Large, evolving systems; GUI applications; simulations Simple scripts, system utilities, low‑level code Mathematical modelling, data transformation, concurrent processing User‑interface programs, web front‑ends, configuration‑driven systems

20.6 Quick Revision Checklist (All Paradigms)

  • Define each paradigm and list its main characteristics.
  • Write a short code fragment that demonstrates the key idea:
    • Class with inheritance (OO)
    • Function with parameters and return value (Procedural)
    • Pure recursive function or map (Functional)
    • Event handler or declarative statement (Event‑driven/Declarative)
  • State one advantage and one disadvantage for each paradigm.
  • Identify situations where one paradigm is preferable to the others.
  • Recall the syntax for exception handling and file I/O – these are often combined with OO examples in Paper 4.

Action‑Oriented Review Checklist (Syllabus Audit)

Syllabus Domain What to Verify in the Notes Typical Gaps & How to Fix Them
1. Information Representation (binary, BCD, ASCII/Unicode, hexadecimal, two’s‑/one’s‑complement, overflow) • All number‑base conversions illustrated with worked examples.
• Binary arithmetic shown step‑by‑step.
• ASCII/Unicode discussion includes why code‑points matter.
*Missing overflow examples* → add a short table showing what happens when an 8‑bit addition exceeds 255.
*No BCD* → insert a real‑world BCD use‑case (e.g., digital clocks) with a conversion example.
2. Multimedia (Graphics & Sound) & Compression • Bitmap vs. vector encoding, colour‑depth calculations, sampling‑rate impact on sound size.
• Lossy vs. loss‑less methods (RLE, JPEG, MP3) with justification scenarios.
*Only bitmap shown* → add a simple vector‑graphic diagram and note when vectors are preferred.
*Compression* → include a side‑by‑side file‑size table for a text, an image and an audio file before/after RLE and a lossy method.
3. Communication & Networks • LAN/WAN characteristics, topologies, client‑server vs. peer‑to‑peer, thin/thick client.
• Ethernet/CSMA‑CD, IP addressing (IPv4/IPv6, subnetting, public vs. private, static vs. dynamic), DNS, URL structure, cloud concepts.
*Subnetting omitted* → add a simple subnet mask calculation (e.g., /24 to 255.255.255.0).
*Cloud* → give a concrete example contrasting SaaS with IaaS.
4. Hardware & Logic • CPU Von‑Neumann model, registers (PC, MAR, MDR, ACC, IX), ALU, CU, clock, bus types, fetch‑execute cycle, interrupts.
• Logic gates (AND, OR, NOT, NAND, NOR, XOR) truth tables, circuit construction, Boolean algebra, Karnaugh maps, flip‑flops, half/full adders.
*Interrupts rarely covered* → insert a diagram of an interrupt service routine flow.
*K‑maps* → provide a 2‑variable example to illustrate minimisation.
5. Processor Fundamentals • Assembly language concepts, addressing modes, two‑pass assembler, sample instruction set, bit‑shifts, masking, simple programs traced step‑wise. *Addressing‑mode table missing* → add a concise table (immediate, direct, indirect, indexed, relative) with a Python‑style pseudo‑code illustration.
6. System Software • OS purposes, management tasks (memory, file, process, I/O), security basics, virtualisation, utility software. *No mention of virtual machines* → insert a brief note on how a JVM exemplifies OS‑level abstraction.

Create an account or Login to take a Quiz

79 views
0 improvement suggestions

Log in to suggest improvements to this note.