Classes and objects
What Are Classes and Objects?
A class is a blueprint for creating objects — a way to bundle data and functionality together. For a broader overview, see Introduction to OOP.
An object is an instance of a class, representing a specific implementation of that blueprint. You’ll see these ideas in practice as you explore Classes and Objects in more depth.
Defining a Class
Defining a class creates a blueprint that can be used to instantiate objects. See more about this concept in Classes and Objects.
class Dog:
def __init__(self, name, breed):
self.name = name # attribute
self.breed = breed # attribute
def bark(self): # method
print(f”{self.name} says woof!”)
Key Parts:
- __init: a constructor that runs when an object is created.
- self: refers to the current object instance.
- name and breed: attributes of the object.
- bark: a method, a function that belongs to the class. See Advanced OOP Concepts.
Creating Objects (Instances)
dog1 = Dog(“Buddy”, “Labrador”)
dog2 = Dog(“Coco”, “Poodle”)
dog1.bark() # Buddy says woof!
dog2.bark() # Coco says woof!
Each object has its own state (data) and can use the class’s methods. For a broader context on encapsulation and how state is managed, see Encapsulation.
Accessing and Modifying Attributes
print(dog1.name) # Buddy
dog1.name = “Max”
print(dog1.name) # Max
Why Use Classes?
- Encapsulation: bundle data + behavior.
- Reusability: define once, create many objects.
- Organization: keeps code clean and modular.
- Extensibility: easy to expand with new methods or attributes.
For a deeper look at extensibility and how classes can be extended, see the Inheritance lesson.
Example with Behavior
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print(“Insufficient funds”)
account = BankAccount(“Alice”, 100)
account.deposit(50)
account.withdraw(30)
print(account.balance) # 120
For real-world applications of object-oriented patterns, see Practical Applications and Project.
Summary:
| Concept | Explanation |
|---|---|
Class |
A template that defines the structure and behavior of objects (instances) |
Object |
A concrete instance created from a class, with its own data and behavior |
Attributes |
Variables that store object state (defined in __init__ as self.attribute) |
Methods |
Functions defined within a class that operate on object data (always take self parameter) |
__init__() |
Constructor method that initializes new objects (automatically called when creating instances) |
Constructors (__init__)
What Is a Constructor?
A constructor is a special method in a class that’s automatically called when a new object (instance) is created. If you want a broader explanation of OOP concepts, see Introduction to OOP.
In Python, this constructor method is named __init__().
Purpose of __init__()
- To initialize attributes (variables) of a new object.
- To ensure each object starts in a well-defined state.
- To optionally accept arguments during object creation.
Basic Syntax
class Person:
def __init__(self, name, age): # Constructor
self.name = name
self.age = age
- self: Refers to the current instance.
- name, age: Parameters used to set object-specific data.
Creating an Object
p1 = Person(“Alice”, 30)
print(p1.name) # Alice
print(p1.age) # 30
When Person(“Alice”, 30) is called:
- Python creates a new Person object.
- Calls __init__() with name=“Alice” and age=30.
- Sets self.name and self.age.
Default Values
You can set default values for parameters:
class Person:
def __init__(self, name=”Unknown”, age=0):
self.name = name
self.age = age
Now you can call Person() with no arguments:
p2 = Person()
print(p2.name, p2.age) # Unknown 0
Points to Remember
| Feature | Description |
|---|---|
Special method |
__init__ is automatically called when creating a new object instance |
Self parameter |
Refers to the current object instance (must be first parameter in method definition) |
Initialization |
Primary purpose is to initialize the object’s attributes and state |
Default values |
Parameters can have default values to make them optional during instantiation |
Not mandatory |
Can be omitted if no initialization logic is required (Python provides default) |
To learn more about constructors and how they interact with subclassing, see the Inheritance lesson.
Without __init__
class Empty:
pass
e = Empty()
This still works — but the object won’t have any initialized attributes unless added manually.
Summary:
- __init__ is Python’s constructor method, used to initialize object attributes.
- It runs automatically when an object is created.
- It makes your classes more flexible, dynamic, and useful.
For a broader look at constructors and class design in real projects, consult the Practical Applications and Project lesson.
Instance and class variables
What Are Instance and Class Variables?
Instance Variables are variables that are specific to each instance (object) of a class.
Class Variables are variables that are shared across all instances of the class. These are stored at the class level and have the same value for every object of the class.
1. Instance Variables
What Are They?
- Instance variables are unique to each object. Every time a new object is created, it can have its own values for instance variables.
- They are typically initialized inside the __init__() constructor.
Learn how Encapsulation helps manage access to these variables and protect object state in our Encapsulation lesson.
Example
class Dog:
def __init__(self, name, age):
self.name = name # instance variable
self.age = age # instance variable
dog1 = Dog(“Buddy”, 3)
dog2 = Dog(“Bella”, 5)
print(dog1.name) # Buddy
print(dog2.name) # Bella
In this case, name and age are instance variables because each dog object can have different values for these attributes.
2. Class Variables
What Are They?
- Class variables are shared across all instances of the class.
- They are typically defined inside the class but outside of any methods.
- Class variables are often used for properties that should be common to all objects, such as a constant or counter.
Example
class Dog:
species = “Canine” # class variable
def __init__(self, name, age):
self.name = name # instance variable
self.age = age # instance variable
dog1 = Dog(“Buddy”, 3)
dog2 = Dog(“Bella”, 5)
print(dog1.species) # Canine
print(dog2.species) # Canine
# Changing class variable for the class
Dog.species = “Dog”
print(dog1.species) # Dog
print(dog2.species) # Dog
Warning:
Modifying a class variable using an instance (e.g., dog1.species = “New species”) will create an instance variable with that name, effectively shadowing the class variable.
Summary:
- Instance Variables: Unique to each object; defined inside the __init__() method using self.
- Class Variables: Shared by all objects of the class; defined directly in the class body.
For a deeper understanding of how class variables interact with inheritance and runtime behavior, see the Advanced OOP Concepts lesson.
Inheritance and polymorphism
What Is Inheritance?
Inheritance is a way to allow a new class (child class) to inherit attributes and methods from an existing class (parent class). This promotes code reuse and allows for creating more specialized classes based on general ones.
Key Concepts:
- Parent Class (or Base Class): The class being inherited from.
- Child Class (or Derived Class): The class that inherits from the parent class.
Example of Inheritance
# Par
Inheritance enables you to create specialized classes that reuse the code in a common base class. This pattern is often paired with polymorphism to allow different child classes to be treated the same way through a shared interface. For a deeper dive, see the Inheritance and Polymorphism lessons.




