Object-Oriented Programming Fundamentals in Python

Object-Oriented Programming Concepts

Programming paradigms represent different approaches to problem-solving using computers. Two primary paradigms exist: procedural and object-oriented programming. Python supports both approaches.

Procedural Programing

This paradigm follows a top-down approach with step-by-step refinement:

  • Problems are broken into sequential steps
  • Complex steps can be further decomposed
  • Functions serve as modular building blocks
  • Core concept: functions as primary organizational units

Object-Oriented Programming

This approach models real-world entities as objects with attributes and behaviors.

Class Definition

Python supports both classic and new-style classes:

class ClassicClass:
    pass

class NewStyleClass(object):
    pass

Classes follow naming conventions (typically PascalCase) and contain attributes and methods.

class Individual(object):
    def consume(self):
        print('eating')
    
    def move(self):
        print('running')

Object Instantiation

Classes are abstract templates that become concrete objects through instantiation:

class Individual(object):
    def consume(self):
        print('eating')
    
    def move(self):
        print('running')

person = Individual()
person.consume()  # eating

Objects occupy memory space and inherit all class attributes and methods.

Instance Attributes and Methods

The self Parameter

The self parameter represents the instance itself within class methods:

class Individual(object):
    def consume(self):
        print('eating')
    
    def introduce(self):
        print(self)

person = Individual()
print(person)      # <__main__.Individual object at 0x...>
person.introduce() # <__main__.Individual object at 0x...>

Adding and Accessing Attributes

Attributes can be added externally or internally:

class Individual(object):
    def consume(self):
        print('eating')
    
    def display_info(self):
        print(f'Name: {self.name}')
        print(f'Age: {self.age}')

# External attribute assignment
person = Individual()
person.name = 'Alex'
person.age = 25
person.display_info()  # Name: Alex, Age: 25

Class Attributes

Shared attributes across all instances:

class Individual(object):
    population = 0
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
        Individual.population += 1

person1 = Individual('John', 30)
person2 = Individual('Jane', 28)
print(Individual.population)  # 2

Class Methods

Methods that operate on class attributes:

class Utility(object):
    count = 0
    
    def __init__(self, name):
        self.name = name
        Utility.count += 1
    
    @classmethod
    def get_count(cls):
        return f'Total instances: {cls.count}'

utility = Utility('hammer')
print(Utility.get_count())  # Total instances: 1

Static Methods

Utility methods that don't require instance or class access:

class StudentSystem(object):
    @staticmethod
    def show_menu():
        print('-' * 40)
        print('Student Management System v1.0')
        print('[1] Add Student')
        print('[2] Remove Student')
        print('[3] Modify Student')
        print('[4] Search Student')
        print('-' * 40)

StudentSystem.show_menu()

Magic Methods

__init__ Constructor

Initializes object attributes during instantiation:

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

individual = Person('Alice', 22)
print(individual.name)  # Alice
print(individual.age)   # 22

__str__ String Representation

Controls object string output:

class Vehicle():
    def __init__(self, brand, model, color):
        self.brand = brand
        self.model = model
        self.color = color
    
    def __str__(self):
        return f'Brand: {self.brand}, Model: {self.model}, Color: {self.color}'

vehicle = Vehicle('BMW', 'X5', 'black')
print(vehicle)  # Brand: BMW, Model: X5, Color: black

__del__ Destructor

Handles cleanup when objects are deleted:

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __del__(self):
        print(f'{self} object deleted')

person = Person('Sarah', 35)
del person  # <__main__.Person object at 0x...> object deleted

Practical Examples

Grade Reporting System

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def report_grade(self):
        if self.score >= 90:
            print(f'{self.name}: {self.score} - Excellent')
        elif 80 <= self.score < 90:
            print(f'{self.name}: {self.score} - Good')
        elif 70 <= self.score < 80:
            print(f'{self.name}: {self.score} - Average')
        elif 60 <= self.score < 70:
            print(f'{self.name}: {self.score} - Pass')
        else:
            print(f'{self.name}: {self.score} - Fail')

student = Student('Tom', 85)
student.report_grade()  # Tom: 85 - Good

Fitness Tracker

class Person(object):
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight
    
    def exercise(self):
        self.weight -= 0.1
    
    def eat(self):
        self.weight += 0.2
    
    def __str__(self):
        return f'{self.name} weighs {self.weight:.2f} kg'

athlete = Person('Mike', 75.0)
athlete.exercise()
print(athlete)  # Mike weighs 74.90 kg
athlete.eat()
print(athlete)  # Mike weighs 75.10 kg

Furniture Arrangement

class Residence(object):
    def __init__(self, location, space):
        self.location = location
        self.space = space
        self.furniture = []
    
    def add_item(self, item):
        required_space = item.get_area()
        if self.space >= required_space:
            self.furniture.append(item)
            self.space -= required_space
            print('Furniture placed successfully')
        else:
            print('Insufficient space for furniture')
    
    def __str__(self):
        info = f'Residence at {self.location}, remaining space: {self.space}'
        if self.furniture:
            info += ', furniture: '
            info += ', '.join([item.get_name() for item in self.furniture])
        return info

class Furniture(object):
    def __init__(self, name, area):
        self.__name = name
        self.__area = area
    
    def get_area(self):
        return self.__area
    
    def get_name(self):
        return self.__name

bed = Furniture('Mattress', 5)
table = Furniture('Desk', 3)
home = Residence('Downtown', 50)
home.add_item(bed)
home.add_item(table)
print(home)  # Residence at Downtown, remaining space: 42, furniture: Mattress, Desk

Core OOP Principles

Encapsulation

Bundling data and methods while controlling access:

class Person(object):
    def __init__(self, name):
        self.__name = name
        self.__age = 18
    
    def get_name(self):
        return self.__name
    
    def get_age(self):
        return self.__age

person = Person('Emma')
print(person.get_age())  # 18

Private attributes use double underscores prefix.

Inheritance

Creating new classes based on existing ones:

class Animal(object):
    def eat(self):
        print('consuming food')
    
    def move(self):
        print('moving')

class Canine(Animal):
    pass

dog = Canine()
dog.eat()   # consuming food
dog.move()  # moving

Single Inheritance

class Vehicle(object):
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model
    
    def drive(self):
        print('driving')

class SportsCar(Vehicle):
    pass

car = SportsCar('Ferrari', 'F40')
print(car.brand)  # Ferrari
print(car.model)  # F40
car.drive()       # driving

Multiple Inheritance

class ElectricEngine(object):
    def power_electric(self):
        print('electric powered')

class GasEngine(object):
    def power_gas(self):
        print('gas powered')

class HybridVehicle(ElectricEngine, GasEngine):
    pass

hybrid = HybridVehicle()
hybrid.power_electric()  # electric powered
hybrid.power_gas()       # gas powered

Method Overriding

class Animal(object):
    def communicate(self):
        print('making sounds')

class Dog(Animal):
    def communicate(self):
        print('barking')

class Cat(Animal):
    def communicate(self):
        print('meowing')

dog = Dog()
cat = Cat()
dog.communicate()  # barking
cat.communicate()  # meowing

Super Function

Accessing parent clas methods:

class Vehicle(object):
    def __init__(self, brand, model, color):
        self.brand = brand
        self.model = model
        self.color = color
    
    def operate(self):
        print('vehicle operating')

class ElectricVehicle(Vehicle):
    def __init__(self, brand, model, color, battery):
        super().__init__(brand, model, color)
        self.battery = battery
    
    def operate(self):
        super().operate()
        print('electric operation')

tesla = ElectricVehicle('Tesla', 'Model 3', 'white', 75)
print(tesla.brand, tesla.battery)  # Tesla 75
tesla.operate()  # vehicle operating
                 # electric operation

Polymorphism

Same interface with different implementations:

class Beverage(object):
    def prepare(self):
        pass

class Coffee(Beverage):
    def prepare(self):
        print('brewing coffee')

class Tea(Beverage):
    def prepare(self):
        print('steeping tea')

def serve_drink(beverage):
    beverage.prepare()

coffee = Coffee()
teacup = Tea()
serve_drink(coffee)  # brewing coffee
serve_drink(teacup)  # steeping tea

Method Resolution Order

Determines inheritance priority in multiple inheritance:

class ElectricEngine(object):
    def start(self):
        print('electric engine starting')

class GasEngine(object):
    def start(self):
        print('gas engine starting')

class HybridVehicle(ElectricEngine, GasEngine):
    pass

print(HybridVehicle.__mro__)
# (<class '__main__.HybridVehicle'>, <class '__main__.ElectricEngine'>, 
#  <class '__main__.GasEngine'>, <class 'object'>)

Object to Dictionary Conversion

Convert object attributes to dictionary format:

class Example(object):
    class_attr = 0
    
    def __init__(self):
        self.instance_attr = 1

obj = Example()
print(obj.__dict__)  # {'instance_attr': 1}

Student Management System Implementation

Main Application

from student_manager import StudentManager

if __name__ == '__main__':
    manager = StudentManager()
    manager.launch()

Student Class

class Student(object):
    def __init__(self, name, age, phone):
        self.name = name
        self.age = age
        self.phone = phone
    
    def __str__(self):
        return f'Name: {self.name}, Age: {self.age}, Phone: {self.phone}'

Manager Class

from student import Student

class StudentManager(object):
    def __init__(self):
        self.students = []
    
    @staticmethod
    def display_menu():
        print('-' * 40)
        print('Student Management System v2.0')
        print('[1] Add Student')
        print('[2] Delete Student')
        print('[3] Update Student')
        print('[4] Search Student')
        print('[5] List All Students')
        print('[6] Save Data')
        print('[0] Exit')
        print('-' * 40)
    
    def add_student(self):
        name = input('Enter student name: ')
        age = input('Enter student age: ')
        phone = input('Enter student phone: ')
        student = Student(name, age, phone)
        self.students.append(student)
        print(student)
        print('Student added successfully')
    
    def delete_student(self):
        name = input('Enter name to delete: ')
        for student in self.students:
            if student.name == name:
                self.students.remove(student)
                print(f'{name} removed')
                return
        print(f'{name} not found')
    
    def update_student(self):
        name = input('Enter name to update: ')
        for student in self.students:
            if student.name == name:
                student.name = input('New name: ')
                student.age = input('New age: ')
                student.phone = input('New phone: ')
                print('Update successful')
                return
        print(f'{name} not found')
    
    def search_student(self):
        name = input('Enter name to search: ')
        for student in self.students:
            if student.name == name:
                print(student)
                return
        print(f'{name} not found')
    
    def list_students(self):
        if self.students:
            for student in self.students:
                print(student)
        else:
            print('No students available')
    
    def save_data(self):
        with open('./students.txt', 'w', encoding='utf-8') as file:
            file.write(str([student.__dict__ for student in self.students]))
        print('Data saved')
    
    def load_data(self):
        try:
            with open('./students.txt', 'r', encoding='utf-8') as file:
                content = file.read()
                if content:
                    data = eval(content)
                    self.students = [Student(item['name'], item['age'], item['phone']) 
                                   for item in data]
        except FileNotFoundError:
            pass
    
    def launch(self):
        self.load_data()
        while True:
            StudentManager.display_menu()
            choice = int(input('Select option: '))
            
            if choice == 1:
                self.add_student()
            elif choice == 2:
                self.delete_student()
            elif choice == 3:
                self.update_student()
            elif choice == 4:
                self.search_student()
            elif choice == 5:
                self.list_students()
            elif choice == 6:
                self.save_data()
            elif choice == 0:
                print('Exiting system')
                break
            else:
                print('Invalid option')

Tags: python OOP Classes Inheritance Polymorphism

Posted on Fri, 22 May 2026 21:19:07 +0000 by vietnamese