Key Takeaways: Object-Oriented Programming — Thinking in Objects

One-Sentence Summary

Object-oriented programming bundles data (attributes) and behavior (methods) into objects created from class blueprints, giving you a powerful way to model real-world concepts and manage complexity in growing programs.

The OOP Mental Model

Concept What It Is Example
Class Blueprint / template class Student:
Object (Instance) A specific thing created from the blueprint alice = Student("Alice", "S001")
Attribute Data the object knows alice.name, alice.grades
Method Behavior the object can perform alice.add_grade("CS101", 92)
self Reference to the current object inside a method Always the first parameter
__init__ Constructor — sets up a new object Runs automatically on creation

Instance vs. Class Attributes

Type Defined Where Shared? Good For
Instance attribute Inside __init__ with self.x = ... No — each object gets its own Names, scores, inventories
Class attribute In the class body, outside any method Yes — one copy for all instances Constants, counters, configuration

Rule: If each object needs its own list, dict, or set, create it in __init__. A class-level mutable attribute is one object shared by every instance, so changing it through one instance changes it for all. (A lookup table that nothing ever modifies, like PRIORITY_ORDER, is fine at class level.)

Essential Special Methods (Dunders)

Method Purpose Called By
__init__(self, ...) Initialize new objects MyClass(...)
__str__(self) Human-readable display print(obj), str(obj)
__repr__(self) Developer/debugging display REPL, repr(obj), containers
__eq__(self, other) Value equality obj1 == obj2
__lt__(self, other) Less-than comparison sorted(), < operator
__len__(self) Length/size len(obj)

Two __eq__ rules: return NotImplemented (don't raise it) when other is a type you don't handle, and remember that defining __eq__ without __hash__ makes your objects unhashable, so they can't go in sets or be dictionary keys.

Encapsulation Conventions

Convention Meaning Access
self.name Public Use freely from anywhere
self._name Internal ("protected") Use at your own risk
self.__name Name-mangled Strongly discouraged external access
@property Controlled access Looks like an attribute, works like a method; set it in __init__ too so validation always runs

When to Use OOP vs. Procedural

Use OOP when: - You're modeling "things" with identity, state, and behavior (nouns: Student, Task, Room) - Multiple related data items belong together - You need multiple instances of the same concept - State changes over time and needs tracking

Stay procedural when: - You're writing stateless utility functions (verbs: calculate, parse, convert) - You have a simple input-to-output transformation - No instances or shared state are needed

Most real programs use both. Classes for domain objects, functions for utilities.

Three Pitfalls to Avoid

  1. Forgetting self — every method needs it as the first parameter, every attribute access uses self.
  2. Mutable class attributes — lists/dicts at the class level are shared between all instances; use __init__ instead
  3. God classes — split large classes into focused ones, each with a single responsibility

The Threshold Concept

Before: "I have data in variables and functions that operate on that data — separately."

After: "I have objects that KNOW things (attributes) and can DO things (methods)."

When you look at a problem and think "this thing has properties and actions," reach for a class.

TaskFlow v1.3 Architecture

Class Responsibility
Task Represents a single task — title, priority, category, completion; to_dict() and the @classmethod from_dict() handle serialization
TaskList Manages a collection of tasks — add, delete, search, filter by priority or category
TaskStorage Handles persistence — save to and load from JSON

What's Next

Chapter 15 introduces inheritance (building new classes on top of existing ones) and polymorphism (different objects responding to the same method in different ways). TaskFlow will gain DeadlineTask, RecurringTask, and ChecklistTask subclasses.