Skip to main content
Python for Beginners
CHAPTER 18 Beginner

Object-Oriented Programming (OOP)

Updated: May 17, 2026
30 min read

# Object-Oriented Programming (OOP)

Welcome to Chapter 18! OOP is one of the most important programming paradigms. It lets you model real-world entities as objects with properties and behaviors.

---

1. Learning Objectives

  • Understand OOP concepts (classes, objects, encapsulation).
  • Create classes with constructors and methods.
  • Use instance and class variables.
  • Implement special/magic methods.
  • Build a bank account system.

---

2. Classes and Objects

```python id="py18ex1" class Dog: # Class variable (shared by all instances) species = "Canis familiaris" # Constructor (initializer) def init_(self, name, breed, age): # Instance variables (unique to each object) self.name = name self.breed = breed self.age = age # Instance method def bark(self): return f"{self.name} says Woof! 🐕" def info(self): return f"{self.name} ({self.breed}), {self.age} years old"

# Creating objects (instances) dog1 = Dog("Buddy", "Labrador", 3) dog2 = Dog("Luna", "German Shepherd", 5)

print(dog1.bark()) # Buddy says Woof! 🐕 print(dog2.info()) # Luna (German Shepherd), 5 years old print(Dog.species) # Canis familiaris

1

Class vs Object: ┌──────────────────┐ │ Class: Dog │ ← Blueprint │ - name │ │ - breed │ │ - bark() │ └──────┬───────────┘ │ Creates ┌───┴───┐ ▼ ▼ ┌──────┐ ┌──────┐ │dog1 │ │dog2 │ ← Instances │Buddy │ │Luna │ └──────┘ └──────┘

123456
---

## 3. The self Parameter

`self` refers to the **current instance** of the class:

python id="py18ex2" class Student: def init_(self, name, grade): self.name = name # self.name = instance variable self.grade = grade def promote(self): self.grade += 1 # Modify instance variable print(f"{self.name} promoted to grade {self.grade}!")

s = Student("Alice", 10) s.promote() # Alice promoted to grade 11!

1234
---

## 4. Class Variables vs Instance Variables

python id="py18ex3" class Employee: # Class variable company = "TechCorp" employeecount = 0 def _init(self, name, salary): self.name = name # Instance variable self.salary = salary # Instance variable Employee.employeecount += 1

e1 = Employee("Alice", 80000) e2 = Employee("Bob", 75000)

print(Employee.company) # TechCorp print(Employee.employee_count) # 2 print(e1.name) # Alice

1234
---

## 5. Methods Types

python id="py18ex4" class MyClass: count = 0 def init(self, value): self.value = value MyClass.count += 1 # Instance method — accesses instance data def show(self): return f"Value: {self.value}" # Class method — accesses class data @classmethod def getcount(cls): return f"Total instances: {cls.count}" # Static method — no access to instance or class @staticmethod def validate(value): return isinstance(value, (int, float))

obj1 = MyClass(10) obj2 = MyClass(20)

print(obj1.show()) # Value: 10 print(MyClass.get_count()) # Total instances: 2 print(MyClass.validate(42)) # True

1234
---

## 6. Magic/Dunder Methods

python id="py18ex5" class Vector: def init(self, x, y): self.x = x self.y = y def str(self): return f"Vector({self.x}, {self.y})" def repr(self): return f"Vector(x={self.x}, y={self.y})" def add(self, other): return Vector(self.x + other.x, self.y + other.y) def len(self): return int((self.x2 + self.y2)**0.5) def eq_(self, other): return self.x == other.x and self.y == other.y

v1 = Vector(3, 4) v2 = Vector(1, 2)

print(v1) # Vector(3, 4) print(v1 + v2) # Vector(4, 6) print(len(v1)) # 5 print(v1 == v2) # False

1234
---

## 7. Properties (Getters and Setters)

python id="py18ex6" class Temperature: def init(self, celsius): self.celsius = celsius @property def celsius(self): return self.celsius @celsius.setter def celsius(self, value): if value < -273.15: raise ValueError("Below absolute zero!") self.celsius = value @property def fahrenheit(self): return (self._celsius * 9/5) + 32

temp = Temperature(100) print(temp.celsius) # 100 print(temp.fahrenheit) # 212.0 temp.celsius = 0 print(temp.fahrenheit) # 32.0

1234
---

## 8. Mini Project: Bank Account System

python id="py18project" class BankAccount: bankname = "PyBank" def _init(self, owner, balance=0): self.owner = owner self.balance = balance self.transactions = [] @property def balance(self): return self.balance def deposit(self, amount): if amount <= 0: raise ValueError("Deposit must be positive!") self.balance += amount self.transactions.append(f"+${amount:.2f}") print(f" ✅ Deposited ${amount:.2f}") def withdraw(self, amount): if amount <= 0: raise ValueError("Withdrawal must be positive!") if amount > self.balance: print(f" ❌ Insufficient funds!") return self.balance -= amount self.transactions.append(f"-${amount:.2f}") print(f" ✅ Withdrew ${amount:.2f}") def statement(self): print(f"\n {'='*35}") print(f" {self.bankname} - Account Statement") print(f" {'='*35}") print(f" Owner: {self.owner}") print(f" Balance: ${self.balance:.2f}") print(f" Transactions: {len(self.transactions)}") for t in self.transactions[-5:]: print(f" {t}") print(f" {'='*35}") def str(self): return f"BankAccount({self.owner}, ${self.balance:.2f})"

# Demo account = BankAccount("Alice", 1000) account.deposit(500) account.withdraw(200) account.withdraw(100) account.statement() ``

---

9. MCQs with Answers

Q1: _init is: A) Destructor B) Constructor C) Iterator D) Generator Answer: B

Q2: self refers to: A) The class B) Current instance C) Parent class D) Module Answer: B

Q3: Class variables are shared by: A) One instance B) All instances C) No instances D) Only methods Answer: B

Q4: @classmethod receives: A) self B) cls C) Nothing D) Both Answer: B

Q5: @staticmethod receives: A) self B) cls C) Nothing special D) Both Answer: C

Q6: str is called by: A) repr() B) print() C) len() D) init() Answer: B

Q7: @property creates: A) Class variable B) Getter method C) Static method D) Private variable Answer: B

Q8: variable convention means: A) Public B) Private (by convention) C) Protected D) Constant Answer: B

Q9: Dunder methods start and end with: A) B) C) # D) @ Answer: B — Double underscores.

Q10: Can a class have multiple constructors? A) Yes, directly B) No, use @classmethod alternatives C) Only in Python 2 D) Only with metaclasses Answer: B — Python uses @classmethod for alternative constructors.

---

10. Interview Questions

  1. 1. What is self? Reference to the current instance, passed automatically as the first argument to instance methods.
  1. 2. Class variable vs instance variable? Class variables are shared across all instances; instance variables are unique to each object.
  1. 3. What are magic/dunder methods? Special methods with double underscores that Python calls implicitly (e.g., init, str, add).
  1. 4. What is the @property decorator? Creates getter/setter methods that look like attributes, enabling validation and computed properties.
  1. 5. Can you have multiple init methods? No. Use @classmethod for alternative constructors.

---

11. Summary

  • Classes are blueprints; objects are instances.
  • init initializes objects; self refers to the current instance.
  • Class variables are shared; instance variables are unique.
  • @classmethod, @staticmethod, and @property provide different method types.
  • Magic methods (str, add_`, etc.) customize object behavior.

---

12. Next Chapter Recommendation

In Chapter 19: Inheritance and Polymorphism, you'll learn to build class hierarchies and reuse code! 🚀

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·