Defining a Class
Use theclass keyword followed by the class name (by convention, PascalCase) and a colon:
The __init__ Method and self
__init__ is the constructor — Python calls it automatically whenever you create a new instance. The first parameter, self, is a reference to the instance being created. Every instance attribute you want the object to have is set on self:
Creating Instances
Call the class like a function to create an instance:student1.name does not affect student2.
Instance Attributes vs Class Attributes
An instance attribute lives on the object itself (set viaself). A class attribute lives on the class and is shared by all instances:
Methods
Instance Methods
Instance methods takeself as their first argument and can read and modify the object’s attributes:
Inheritance
Inheritance lets a child class reuse everything from a parent class and add or override behaviour as needed. This avoids duplicating code across similar classes.Dog subclass that inherits from Animal:
super()
super() gives you access to the parent class’s methods. You almost always call super().__init__() in a child’s constructor so the parent can set up its own attributes before the child adds its own.
Overriding Methods
Override a parent method in the child to change its behaviour:Practical Example: Product and Cart
Here is a realistic example that models an e-commerce cart. It demonstrates instance attributes, methods, inheritance, and__str__ for readable printing:
When to Use OOP vs Functions
Prefer classes when…
Prefer classes when…
- You have data and behaviour that naturally belong together (e.g., a
BankAccounthas a balance and deposit/withdraw methods). - You need multiple instances of the same kind of thing, each with its own state.
- You want inheritance to avoid repeating yourself across similar types.
- You are building a larger application where encapsulation and clear boundaries matter.
Prefer functions when…
Prefer functions when…
- The logic is a simple transformation: input → output with no persistent state.
- You are writing small scripts or one-off data processing pipelines.
- Keeping things functional makes the code easier to test in isolation.
- A class would only ever have one instance and no meaningful attributes.
Key Takeaways
Class = blueprint
A class defines the structure. Every
instance = ClassName() call creates a separate object with its own copy of instance attributes.self is the instance
Always include
self as the first parameter in instance methods. Python passes the instance automatically when you call obj.method().Inheritance shares code
Use inheritance to let child classes reuse parent code. Call
super().__init__() in the child’s constructor to ensure the parent sets up correctly first.Override, don't repeat
Override a parent method in a child class when the behaviour needs to differ. The parent method is still accessible via
super().method_name().