DEV Community

Cover image for Object Oriented programming
Kenyansa Felix Amenya
Kenyansa Felix Amenya

Posted on

Object Oriented programming

Guide to Understanding Classes in Object-Oriented Programming:

What is a Class?
In Object-Oriented Programming (OOP), a class is like a blueprint or template for creating objects. Think of it as a cookie cutter that defines the shape and ingredients of cookies, while the cookies themselves are the objects. A class encapsulates data (attributes) and behaviors (methods) that operate on that data into a single, organized unit.

Why Classes are Useful?
Classes solve several programming challenges:

  1. Organization: They group related data and functions together
  2. Reusability: Once defined, a class can create multiple similar objects
  3. Abstraction: They hide complex implementation details
  4. Modularity: Different parts of a program can be developed independently
  5. Real-world modeling: They help represent real-world entities in code Key Components: Attributes and MethodsAttributes: Variables that store data (like characteristics of an object) • Methods: Functions that define behaviors or actions the object can perform

Lets use an Example: BankAccount Class
class BankAccount:
** A simple BankAccount class to demonstrate OOP concepts**


    def __init__(self, account_number, owner, initial_balance=0):
        """
        Constructor method - called when creating a new BankAccount object
        :param account_number: Unique account identifier
        :param owner: Name of account owner
        :param initial_balance: Starting balance (defaults to 0)
        """
        # These are ATTRIBUTES (data/properties)
        self.account_number = account_number
        self.owner = owner
        self.balance = initial_balance
        print(f"Account created for {self.owner} with balance: ${self.balance:.2f}")

   ** # These are METHODS (behaviors/actions)**

    def deposit(self, amount):
        """Add money to the account"""
        if amount > 0:
            self.balance += amount
            print(f"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}")
        else:
            print("Deposit amount must be positive!")
        return self.balance

    def withdraw(self, amount):
        """Remove money from the account if sufficient funds exist"""
        if amount > 0:
            if amount <= self.balance:
                self.balance -= amount
                print(f"Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}")
            else:
                print(f"Insufficient funds! Available: ${self.balance:.2f}")
        else:
            print("Withdrawal amount must be positive!")
        return self.balance

    def check_balance(self):
        """Return the current balance"""
        print(f"Account balance for {self.owner}: ${self.balance:.2f}")
        return self.balance

    def account_info(self):
        """Display all account information"""
        print("\n" + "="*40)
        print("ACCOUNT INFORMATION")
        print("="*40)
        print(f"Owner: {self.owner}")
        print(f"Account Number: {self.account_number}")
        print(f"Current Balance: ${self.balance:.2f}")
        print("="*40 + "\n")
Enter fullscreen mode Exit fullscreen mode

Creating and Using Objects
Creating objects (instances) from the BankAccount class
Each object is independent with its own data

Create Alice's account with $1000 initial deposit
alice_account = BankAccount("ACC001", "Alice Johnson", 1000)

Create Bob's account with default $0 balance
bob_account = BankAccount("ACC002", "Bob Smith")

Using methods on Alice's account
alice_account.deposit(500) # Alice deposits $500
alice_account.withdraw(200) # Alice withdraws $200
alice_account.check_balance() # Check Alice's balance
alice_account.account_info() # Get full account info

Using methods on Bob's account

bob_account.deposit(100) # Bob deposits $100
bob_account.withdraw(50) # Bob withdraws $50
bob_account.withdraw(100) # This should fail - insufficient funds

Each object maintains its own state
print(f"\nAlice's balance: ${alice_account.balance:.2f}")
print(f"Bob's balance: ${bob_account.balance:.2f}")

Direct attribute access (though usually done through methods)
print(f"\nAlice's account number: {alice_account.account_number}")

How Classes Structure Real-World Problems
Our BankAccount example demonstrates how classes help structure programming problems:

  1. Encapsulation: All bank account-related data and operations are in one place
  2. State Management: Each account maintains its own balance independently
  3. Controlled Interaction: Methods like withdraw() include validation logic
  4. Clear Interface: Other parts of the program can use accounts without knowing internal details
  5. Extending the Class (Optional Challenge) class EnhancedBankAccount(BankAccount):

An extended version with additional features


    def __init__(self, account_number, owner, initial_balance=0, account_type="Savings"):
        # Call parent class constructor
        super().__init__(account_number, owner, initial_balance)
        self.account_type = account_type
        self.transaction_history = []

    def deposit(self, amount):
        # Extend the parent method
        result = super().deposit(amount)
        self.transaction_history.append(f"Deposit: +${amount:.2f}")
        return result

    def withdraw(self, amount):
        result = super().withdraw(amount)
        self.transaction_history.append(f"Withdrawal: -${amount:.2f}")
        return result
Enter fullscreen mode Exit fullscreen mode

Best Practices for Beginners

  1. Meaningful Names: Use descriptive names for classes, attributes, and methods
  2. Single Responsibility: Each class should have one clear purpose
  3. Use Methods for Actions: Change attributes through methods rather than directly
  4. Start Simple: Begin with basic classes and add complexity gradually
  5. Practice: Create classes for everyday objects (Book, Car, Student, etc.)

Example

bank_account_demo.py

This is a complete BankAccount Class Example

Save this as bank_account_demo.py and run it with Python

Lets write a simple BankAccount class to demonstrate OOP concepts

class BankAccount:
    def __init__(self, account_number, owner, initial_balance=0):
        self.account_number = account_number
        self.owner = owner
        self.balance = initial_balance
        print(f"Account created for {self.owner} with balance: ${self.balance:.2f}")

    def deposit(self, amount):
        if amount > 0:
            self.balance += amount
            print(f"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}")
        else:
            print("Deposit amount must be positive!")
        return self.balance

    def withdraw(self, amount):
        if amount > 0:
            if amount <= self.balance:
                self.balance -= amount
                print(f"Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}")
            else:
                print(f"Insufficient funds! Available: ${self.balance:.2f}")
        else:
            print("Withdrawal amount must be positive!")
        return self.balance

    def check_balance(self):
        print(f"Account balance for {self.owner}: ${self.balance:.2f}")
        return self.balance
Enter fullscreen mode Exit fullscreen mode

Main execution

if __name__ == "__main__":
    print("=== BANK ACCOUNT DEMONSTRATION ===\n")

    # Create accounts
    account1 = BankAccount("ACC001", "Alice Johnson", 1000)
    account2 = BankAccount("ACC002", "Bob Smith")

    print("\n=== Performing Transactions ===\n")

    # Account 1 transactions
    account1.deposit(500)
    account1.withdraw(200)

    # Account 2 transactions
    account2.deposit(300)
    account2.withdraw(100)
    account2.withdraw(250)  # Should fail

    print("\n=== Final Balances ===\n")
    account1.check_balance()
    account2.check_balance()
Enter fullscreen mode Exit fullscreen mode

Conclusion
Classes are fundamental to Object-Oriented Programming because they provide a structured way to model real-world entities. By bundling related data and behaviors together, they make code more organized, reusable, and easier to understand. The BankAccount example demonstrates how even beginners can create useful, real-world simulations using classes. As you practice, you'll discover that classes are powerful tools for breaking down complex problems into manageable, logical units.
Remember: A class defines what an object is (attributes) and what it does (methods), while objects are the actual instances you work with in your program.

Top comments (0)