Matua Doc

Introduction to object-oriented programming

Learning intentions

In this lesson, you will build a practical foundation for object-oriented programming in Swift and use it to model real problems more clearly. Explain object-oriented programming in simple terms using real-world examples, then describe what a struct is and why it is often the best starting model type in Swift, and create your own instances and test that they store and report data correctly.

You will also connect these ideas to code quality so your programs are easier to read and maintain over time. Keep related data and behaviour together so each model has a clear purpose, which helps you use model types to make code easier to understand and easier to update over time.

What is object-oriented programming?

Object-oriented programming is a way of designing software around models that represent real things or concepts in your program. Data and behaviour stay connected instead of being scattered across unrelated files, while types act like blueprints that describe what data and actions a model should have, and instances are real values created from those blueprints and used directly in your code.

Stacked blocks

Why developers use object-oriented ideas

Object-oriented design helps teams grow codebases without losing clarity, because each model keeps related logic in one place. Related logic stays in one place so features are easier to find and change and reusable models reduce duplication across screens, functions, and modules.

It also supports safer refactoring and collaboration, because clearer boundaries make it easier to track where a change belongs especially when projects grow beyond one file. Clear model boundaries make bugs easier to locate because ownership of logic is obvious, and shared types make collaboration easier by giving teams one consistent structure to work from.

Types and instances in Swift

In Swift, built-in types such as Int, String, and Array already follow this model-based style, and custom types work the same way. Int is a type which defines what kind of value can be stored, let age = 18 creates an instance which is one concrete value of that type, and the same pattern applies to custom models like Player, Book, or Quest.

When you define your own struct, you are creating a model for your own domain, so choose names that match the problem you are solving. Use names tied to the problem space so intent is obvious to readers.

What is a struct?

A struct is a custom type that groups related properties and methods so one model can hold data and define behaviour together. Stored properties hold data that describes the current state of the model, methods define behaviour so the model can act on its own data, and each instance gets its own copy of stored values which avoids accidental shared state.

For beginner and intermediate Swift projects, struct is usually the best default because value semantics reduce accidental shared-state bugs and make behaviour easier to reason about.

Anatomy of a struct

A useful struct has a clear name, meaningful properties, and behaviour that naturally belongs to the model itself. Keep property names specific so readers immediately understand each value, and keep method names action-focused so behaviour is easier to scan and reason about.

struct Player {
    var name: String
    var score: Int

    func summary() -> String {
        return "\(name) has \(score) points."
    }
}

Creating instances

You create an instance by calling the type and passing values for its stored properties. Use Swift's memberwise initializer to quickly create complete model values, and choose variable names that read clearly in context especially when multiple instances exist.

let firstPlayer = Player(name: "Aria", score: 10)
let secondPlayer = Player(name: "Niko", score: 3)

Accessing properties and methods

After creating an instance, use dot syntax to read properties and call methods so your code can access both data and behaviour cleanly. player.name reads a property value directly from the instance, while player.summary() calls a method that uses instance data to produce output.

print(firstPlayer.name)      // Aria
print(firstPlayer.summary()) // Aria has 10 points.

Designing better structs

Strong structs model one concept well instead of trying to solve multiple unrelated problems at once. Keep each struct focused on one responsibility so the model stays small and coherent, avoid unrelated properties that make the type harder to understand and maintain, and add methods only when behaviour belongs to that model and its purpose.

This keeps your code easier to read, test, and change and helps prevent model types from becoming "god objects".

Testing struct behaviour

When testing a struct, check both how data is stored and how methods behave so you can trust the model in different scenarios. Verify properties after initialization to confirm values were assigned as expected, verify method return values to ensure behaviour matches your design rules, and use multiple instances to confirm data independence and prevent cross-instance bugs.

let a = Player(name: "Tui", score: 0)
let b = Player(name: "Moana", score: 7)

print(a.summary()) // Tui has 0 points.
print(b.summary()) // Moana has 7 points.

Task A: race garage

  1. Create a struct called Car with properties brand, model, and year.
  2. Create two Car instances and print a sentence about each car.
  3. Use dot syntax to print each property value.

Task B: mini banking model

  1. Create a struct called BankAccount with properties owner and balance.
  2. Add a method named description() that returns a sentence with both values.
  3. Create two accounts and print description() for each one.

Task C: area checker

  1. Create a struct called Rectangle with properties width and height.
  2. Add a method named area() that returns the area.
  3. Create two rectangles
  4. Print both areas
  5. Determine which rectangle is the larger using some function or conditional statements.

Task D: quest board

  1. Create a struct called Quest with properties title, difficulty, and reward.
  2. Add a method printBadge() that prints a formatted line such as "Rescue the Prince - Hard Quest - 50 XP".
  3. Create three quest instances of different difficulties.
  4. Call printBadge() for each.
  5. Determine which quest is hardest using some function or conditional statements.

Summary

Object-oriented programming helps you model software around meaningful entities so code is easier to organize and reason about. Types define the blueprint for what data and behaviour a model can contain, instances store real values that your program can read, update, and pass around, and structs combine data and behaviour cleanly which improves structure and clarity.

Used consistently, these ideas improve readability, testing, and long-term maintainability especially as your codebase grows.

Review

Use these prompts to check your understanding and explain each idea in your own words. Explain object-oriented programming in one sentence using your own wording, define what a Swift struct is and when it should be used, describe the difference between a type definition and an instance value, and write a struct with one method and test it with at least two separate instances.