💻 Comprehensive Study Notes: Object-Oriented and Additional Programming (9645)

Hello future Computer Scientist! Welcome to the section on Object-Oriented Programming (OOP) and other crucial advanced programming techniques. These concepts might seem abstract at first, but they are the foundation of modern, large-scale software development. Don't worry! We'll break them down into simple, manageable pieces. By the end of this chapter, you’ll understand how to design robust, flexible, and reusable code.

Let's dive in!


1. Object-Oriented Programming (OOP) Fundamentals (3.9.1)

OOP is a powerful programming approach that structures code around objects rather than just functions and logic. It helps us manage complexity by modelling real-world entities directly in our programs.

What is a Class? (The Blueprint)

A Class is essentially a blueprint, template, or definition for creating objects. It defines the general characteristics (data) and behaviours (actions) that all objects of that type will possess.

  • Analogy: Think of a Class like the blueprint for a car factory. It specifies that every car must have four wheels, an engine, and methods like start() and accelerate().
Properties / Attributes

These are the data fields that define the state of an object. They capture the characteristics.

  • Example: If the Class is Car, attributes would be colour, speed, and fuelLevel.
Methods

These are the functions or procedures defined within the class that determine the actions or behaviours an object can perform.

  • Example: For the Car class, methods would include startEngine(), brake(), or refuel().

What is an Object? (The Actual Thing)

An Object is a tangible instance of a class. Once you create an object, it has specific, distinct values for its attributes.

  • Analogy: The car blueprint (Class) is abstract. Your specific red Toyota Corolla parked outside (Object) is concrete and instantiated from that blueprint.
Instantiation

Instantiation is the process of creating an object from a class. When you instantiate a class, you are asking the computer to allocate memory for that specific object and its unique data.

Constructors

A constructor is a special type of method that is automatically called when an object is instantiated. Its main job is to initialise the object to a given state.

  • If you create a Car object, the constructor might automatically set the initial speed to 0 and the fuelLevel to 50 litres.
Quick Review: The OOP Core

Class: Blueprint (Defines structure)
Object: Instance (The actual structure built)
Constructor: Initializer (Sets the object's starting data)


2. Encapsulation (Hiding the Details) (3.9.2)

Encapsulation is one of the pillars of OOP. It means bundling the data (attributes/properties) and the methods that operate on that data into a single unit (the class), and critically, hiding the internal ways a class operates and how it represents data from other classes.

Why Use Encapsulation?

It protects the integrity of the data. If internal data can only be changed by controlled methods (not directly), you can ensure the data remains valid. (E.g., you can ensure speed never goes below zero.)

Access Modifiers (Access Specifiers)

Access modifiers are keywords used to define the visibility and accessibility of a class's members (properties and methods).

  • Public (+): Accessible from anywhere in the program, including outside the class. (The car horn - anyone can use it.)
  • Private (-): Accessible only within the class where they are declared. (The internal engine temperature gauge - only the engine methods need to see this.)
  • Protected (#): Accessible within the class itself and by any subclasses that inherit from it. (Maintenance routines known only to the car and its specialized truck version.)
Getters and Setters

Since private data cannot be accessed directly by objects outside the class, we use special public methods called Getter and Setter methods to provide controlled access.

  • Getter: A method used to retrieve (get) the value of a private attribute.
  • Setter: A method used to modify (set) the value of a private attribute. Setters often include validation logic to ensure the new value is sensible.

Analogy: Think of a bank account. The account balance (data) is private. You can’t reach in and change the number directly. You must use a public method like deposit() (a setter) or checkBalance() (a getter). These methods protect the data.


3. Relationships Between Classes (3.9.3)

Real-world systems involve many interacting components. In OOP, classes must form relationships to model this interaction.

Inheritance (The "Is-a" Relationship)

Inheritance is a relationship where one class (the subclass or derived class) is a more specialized version of an existing class (the base class or parent class).

  • It promotes code re-use, as the subclass automatically gains all the properties and methods of the base class.
  • Example: A Truck class (subclass) inherits from a Vehicle class (base class). A Truck *is a* Vehicle.
Overriding

Overriding is when a subclass redefines a method that it inherited from its base class. This allows the subclass to behave differently for that specific method while keeping the same method name.

  • Example: Both Car and Motorcycle (subclasses of Vehicle) have a drive() method. The Motorcycle's drive() method would be overridden to include behaviour specific to two wheels, not four.

Association (The "Uses-a" Relationship)

Association is a general relationship between two objects where one object can make use of another object.

  • It is a weaker relationship than inheritance.
  • Example: In a football simulation, a Team object is associated with multiple Player objects. The Team *uses* the Players.
Class Diagrams Notation

You must be familiar with the basic UML (Unified Modeling Language) notation to show these relationships:

  • Inheritance: Shown by a solid line with a hollow arrowhead pointing from the subclass up to the base class.
  • Association: Shown by a solid line between two classes, often labelled to describe the relationship.
  • Access Modifiers in Diagrams:
    • + (Public)
    • - (Private)
    • # (Protected)

4. Additional Programming Techniques (3.9.4)

4.1 File Handling (Text Files) (3.9.4.1)

In the "Additional Programming" section, you need to know how to interact with the computer's persistent storage by reading data from and writing data to text files.

  • Writing: Opening a file, sending data (strings) to it line by line, and closing the file to save the changes permanently.
  • Reading: Opening a file, sequentially retrieving data (strings) from it, and closing the file.

Text files are crucial because they allow programs to store configuration settings, user input, or results that need to persist even after the program has stopped running.

4.2 Recursion (Subroutines that Call Themselves) (3.9.4.2)

A recursive subroutine is a function or procedure that calls itself in order to solve a problem. It’s a powerful tool often used for problems that can be broken down into identical, smaller versions of themselves, such as calculating factorials or traversing trees.

To prevent a recursive subroutine from running forever (an infinite loop, leading to a stack overflow error), every recursive function must have two crucial components:

1. The Base Case

The Base Case is the stopping condition. It is the condition in which the subroutine does not call itself. When this case is reached, the function returns a result, and the recursive process unwinds.

  • If you forget the base case, your program will crash!
2. The Recursive Case

The Recursive Case is the part where the subroutine calls itself, usually with a smaller input, moving closer to the base case.

Step-by-Step Example: Calculating Factorial (n!)

Factorial is defined as \(n! = n \times (n-1) \times (n-2) \times \dots \times 1\).

Let's define a recursive function Factorial(n):

  1. Base Case: If \(n = 0\), return 1. (0! is defined as 1.)
  2. Recursive Case: If \(n > 0\), return \(n \times \text{Factorial}(n-1)\).

Tracing Factorial(4):

Factorial(4) calls 4 * Factorial(3)
Factorial(3) calls 3 * Factorial(2)
↳ ↳ Factorial(2) calls 2 * Factorial(1)
↳ ↳ ↳ Factorial(1) calls 1 * Factorial(0)
↳ ↳ ↳ ↳ Factorial(0) hits Base Case, returns 1.
↳ ↳ ↳ Returns 1 * 1 = 1
↳ ↳ Returns 2 * 1 = 2
↳ Returns 3 * 2 = 6
↳ Returns 4 * 6 = 24

The final result is 24.

💡 Memory Aid for Recursion: S-U-R

When tracing recursion, remember the flow:
1. Start: Call the function.
2. Unwind: Continue calling (stacking up calls) until the Base Case.
3. Return: Once the Base Case is hit, return the values up the stack to get the final answer.


Key Takeaways from Additional Programming

The concepts of OOP—Classes, Objects, Inheritance, and Encapsulation—help you write code that is modular, easier to debug, and reusable. Understanding file handling ensures your data persists, and mastering recursion provides an elegant way to solve complex, self-similar problems efficiently.

Keep practising your tracing skills, especially for recursion and basic OOP concepts like instantiation, and you'll master this section!