Master Classes, Objects, Inheritance, and More | House of Script
Object-Oriented Programming (OOP) is a programming paradigm that organizes code into reusable structures called classes and objects. It helps you write cleaner, more maintainable, and scalable code.
A blueprint or template for creating objects. Defines attributes (data) and methods (behavior).
Instances of a class. Each object has its own state (attribute values) while sharing the class structure.
Bundling data and methods together, hiding internal details with private attributes (using _ prefix).
Creating new classes based on existing ones, inheriting attributes and methods while adding new functionality.
Using the same interface for different data types. Methods with the same name behave differently in different classes.
Hiding complex implementation details and showing only essential features to the user.
class Dog:
# The __init__ method is the constructor
def __init__(self, name, breed):
self.name = name # Instance variable
self.breed = breed # Instance variable
# Instance method
def bark(self):
return f"{self.name} says Woof!"
# Creating objects (instances)
dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Max", "Beagle")
print(dog1.bark()) # Output: Buddy says Woof!
print(dog2.name) # Output: Maxself - Refers to the instance itself, must be the first parameter in instance methods__init__ - Constructor method, automatically called when creating an objectInstance variables - Unique to each object (self.name, self.breed)class Car:
# Class variable - shared by all instances
wheels = 4
def __init__(self, brand, model):
# Instance variables - unique to each object
self.brand = brand
self.model = model
car1 = Car("Toyota", "Camry")
car2 = Car("Honda", "Civic")
print(car1.wheels) # 4 (class variable)
print(car2.wheels) # 4 (same class variable)
# Changing class variable affects all instances
Car.wheels = 6
print(car1.wheels) # 6class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
# Dog inherits from Animal
class Dog(Animal):
def speak(self):
return f"{self.name} barks: Woof!"
# Cat inherits from Animal
class Cat(Animal):
def speak(self):
return f"{self.name} meows: Meow!"
dog = Dog("Rex")
cat = Cat("Whiskers")
print(dog.speak()) # Rex barks: Woof!
print(cat.speak()) # Whiskers meows: Meow!Used to call methods from the parent class, especially useful in constructors.
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
class Manager(Employee):
def __init__(self, name, salary, department):
# Call parent constructor using super()
super().__init__(name, salary)
self.department = department
def display_info(self):
return f"{self.name} manages {self.department}"
mgr = Manager("Alice", 80000, "Engineering")
print(mgr.display_info())Use underscore (_) prefix to indicate private attributes (convention, not enforced).
class BankAccount:
def __init__(self, owner):
self.owner = owner
self._balance = 0 # Private attribute (by convention)
def deposit(self, amount):
if amount > 0:
self._balance += amount
def get_balance(self):
return self._balance
account = BankAccount("John")
account.deposit(1000)
print(account.get_balance()) # 1000Special methods with double underscores that enable operator overloading and special behavior.
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
# String representation for users
def __str__(self):
return f"'{self.title}' by {self.author}"
# String representation for developers
def __repr__(self):
return f"Book('{self.title}', '{self.author}', {self.pages})"
# Length of object
def __len__(self):
return self.pages
# Comparison operators
def __eq__(self, other):
return self.pages == other.pages
book = Book("Python Mastery", "Jane Doe", 350)
print(book) # 'Python Mastery' by Jane Doe
print(len(book)) # 350
print(repr(book)) # Book('Python Mastery', 'Jane Doe', 350)__init__ - Constructor__str__ - User-friendly string representation__repr__ - Developer-friendly representation__len__ - Define behavior for len()__eq__ - Define equality (==)__lt__ - Less than (<)__add__ - Addition (+)The ability to use the same interface for different data types.
class Shape:
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
# Polymorphism in action
shapes = [Rectangle(5, 10), Circle(7)]
for shape in shapes:
print(f"Area: {shape.area()}")Design your own Python class visually and see the generated code.
Create objects from predefined classes and inspect their state.
Explore how classes inherit from parent classes in a visual hierarchy.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"class Vehicle:
def __init__(self, brand):
self.brand = brand
class Car(Vehicle):
def __init__(self, brand, doors):
super().__init__(brand)
self.doors = doors
class ElectricCar(Car):
def __init__(self, brand, doors, battery):
super().__init__(brand, doors)
self.battery = batteryBankAccountowner and initialize balance to 0deposit(amount) method that adds to the balancewithdraw(amount) method that subtracts from balance (check for sufficient funds)show_balance() method that displays the current balanceclass BankAccount:
def __init__(self, owner):
self.owner = owner
self.balance = 0
def deposit(self, amount):
self.balance += amount
print(f"{self.owner} deposited ${amount}")
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
print(f"{self.owner} withdrew ${amount}")
else:
print("Insufficient funds.")
def show_balance(self):
print(f"{self.owner}'s balance: ${self.balance}")
# Test the class
account = BankAccount("Alice")
account.deposit(1000)
account.withdraw(250)
account.show_balance()
account.withdraw(1000) # Should show insufficient fundsPet class with attributes: name, species, age__str__ method to display pet information nicelyclass Pet:
def __init__(self, name, species, age):
self.name = name
self.species = species
self.age = age
def __str__(self):
return f"{self.name} ({self.species}), Age: {self.age}"
# Pet registry
pet_registry = []
def add_pet(name, species, age):
pet = Pet(name, species, age)
pet_registry.append(pet)
print(f"Added: {pet}")
def view_pets():
if not pet_registry:
print("No pets in registry.")
else:
print("\n=== Pet Registry ===")
for i, pet in enumerate(pet_registry, 1):
print(f"{i}. {pet}")
# Example usage
add_pet("Buddy", "Dog", 3)
add_pet("Whiskers", "Cat", 2)
add_pet("Tweety", "Bird", 1)
view_pets()Student class with name and a list of gradesadd_grade(grade) methodget_average() methodget_letter_grade() method (A: 90-100, B: 80-89, etc.)__str__ to display student infoclass Student:
def __init__(self, name):
self.name = name
self.grades = []
def add_grade(self, grade):
if 0 <= grade <= 100:
self.grades.append(grade)
else:
print("Grade must be between 0 and 100")
def get_average(self):
if not self.grades:
return 0
return sum(self.grades) / len(self.grades)
def get_letter_grade(self):
avg = self.get_average()
if avg >= 90: return 'A'
elif avg >= 80: return 'B'
elif avg >= 70: return 'C'
elif avg >= 60: return 'D'
else: return 'F'
def __str__(self):
return f"{self.name}: Average = {self.get_average():.1f}, Grade = {self.get_letter_grade()}"
# Test
student = Student("Bob")
student.add_grade(85)
student.add_grade(92)
student.add_grade(78)
print(student)Test your knowledge of OOP concepts in Python!