Skip to main content
Design Patterns – Complete Beginner to Advanced Guide
CHAPTER 02 Intermediate

Object-Oriented Programming Fundamentals

Updated: May 16, 2026
25 min read

# CHAPTER 2

Object-Oriented Programming Fundamentals

1. Introduction

Design patterns are almost exclusively built upon the principles of Object-Oriented Programming (OOP). If you do not intimately understand classes, interfaces, and polymorphism, attempting to learn the Abstract Factory or Observer patterns will be an exercise in frustration. OOP is a programming paradigm based on the concept of "objects," which can contain data (attributes) and code (methods). In this chapter, we will master the foundational pillars of OOP. We will build classes, hide data using encapsulation, share logic via inheritance, and unlock the true power of design patterns through polymorphism and abstraction.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define the difference between a Class and an Object.
  • Implement Encapsulation to protect internal object state.
  • Utilize Inheritance to share code between related classes.
  • Understand Abstraction and the use of Interfaces/Abstract Classes.
  • Master Polymorphism to write flexible, interchangeable code.

3. Classes and Objects

The foundation of OOP is modeling real-world concepts.
  • The Class (The Blueprint): A class is a template. It defines what properties and methods an entity *will* have. (e.g., A Car class defines that all cars will have a color and a startEngine() method).
  • The Object (The Instance): An object is a specific, physical realization of a class. (e.g., myHonda is an object created from the Car class. Its specific color is "Red").

4. Encapsulation (Data Hiding)

Encapsulation is the practice of restricting direct access to an object's data, and bundling the data with the methods that operate on it.
  • The Concept: You should not be able to directly change the balance of a Bank Account variable from outside the class. You must go through a secure method.
  • Access Modifiers:
  • public: Accessible from anywhere.
  • private: Accessible ONLY from inside the class itself.
  • protected: Accessible from the class and its children (subclasses).

5. Inheritance

Inheritance allows a new class (Child) to inherit the properties and methods of an existing class (Parent).
  • The Benefit: Code reuse. If a Dog and a Cat both share 90% of the same logic (eating, sleeping), you create an Animal parent class. The Dog class *extends* Animal, getting all that code for free, and then adds its specific bark() method.

6. Abstraction and Polymorphism

These two concepts are the absolute core of all design patterns.
  • Abstraction: Hiding complex implementation details and showing only the essential features. This is achieved using Interfaces or Abstract Classes. An interface defines a *contract* (e.g., "Any class that implements PaymentMethod MUST have a pay() method").
  • Polymorphism ("Many Forms"): The ability of different classes to be treated as instances of the same class through a common interface. If CreditCard and PayPal both implement the PaymentMethod interface, your checkout code doesn't care which one the user selected; it just calls pay(), and the correct specific logic executes.

7. Diagrams/Visual Suggestions

*OOP Diagram: Inheritance and Polymorphism*
text
123456789
           [ Interface: PaymentMethod ]
                  + pay(amount)
                        ^
                        | (Implements)
           ---------------------------
           |                         |
[ Class: CreditCard ]      [ Class: PayPal ]
  + pay(amount)              + pay(amount)
  + verifyCVV()              + loginToAPI()

8. Code Examples

Let's look at Polymorphism in action using PHP.
php
1234567891011121314151617181920212223242526272829303132
<?php
// Abstraction: The Contract
interface PaymentMethod {
    public function pay($amount);
}

// Implementation 1
class CreditCard implements PaymentMethod {
    public function pay($amount) {
        echo "Processing $" . $amount . " via Credit Card.\n";
    }
}

// Implementation 2
class PayPal implements PaymentMethod {
    public function pay($amount) {
        echo "Processing $" . $amount . " via PayPal API.\n";
    }
}

// Polymorphism in action: The Checkout class doesn't care WHICH payment method it receives.
class Checkout {
    public function processOrder(PaymentMethod $method, $total) {
        // It just knows it can call pay()
        $method->pay($total); 
    }
}

$cart = new Checkout();
$cart->processOrder(new CreditCard(), 100); // Outputs: Processing $100 via Credit Card.
$cart->processOrder(new PayPal(), 50);      // Outputs: Processing $50 via PayPal API.
?>

9. Best Practices

  • Favor Composition Over Inheritance: A massive mistake in OOP is building massive, deeply nested inheritance trees (e.g., Car extends Vehicle extends Machine extends Object). This makes code rigid and fragile. Instead, use Composition: build small classes and *inject* them into other classes. (e.g., A Car *has an* Engine, rather than a Car *is a* Machine).

10. Mini Project: Build an Animal Hierarchy

  1. 1. Create an abstract class Animal with a private property name and an abstract method makeSound().
  1. 2. Create two subclasses: Dog and Cat.
  1. 3. Implement the makeSound() method differently for both (Woof vs Meow).
  1. 4. Write a loop that iterates through an array of Animal objects, calling makeSound() on each, demonstrating polymorphism.

11. Practice Exercises

  1. 1. Define Encapsulation. Why is making class properties public generally considered bad practice in enterprise software?
  1. 2. Explain Polymorphism in your own words. How does an Interface enable Polymorphism?

12. MCQs with Answers

Question 1

Which OOP principle is focused on hiding the internal state of an object and requiring all interaction to be performed through an object's methods (getters/setters)?

Question 2

You have an Interface called Notification with a method send(). The classes EmailNotification and SMSNotification both implement this interface. If a function accepts the Notification interface as a parameter, allowing it to work seamlessly with both Email and SMS classes, which OOP principle is being utilized?

13. Interview Questions

  • Q: Explain the difference between an Abstract Class and an Interface. In what scenario would you choose to use one over the other?
  • Q: Walk me through the concept of "Favor Composition over Inheritance." Why are deep inheritance hierarchies considered an anti-pattern in modern OOP?
  • Q: Describe Encapsulation. What are access modifiers (public, private, protected), and how do they enforce data hiding?

14. FAQs

Q: Do I have to use classes to write good software? A: Not necessarily. Functional Programming (FP) is another massively popular paradigm that avoids mutable state and classes entirely. However, the vast majority of Enterprise Design Patterns (The Gang of Four patterns) are strictly object-oriented.

15. Summary

In Chapter 2, we mastered the core grammar of modern software design. We defined Classes as blueprints and Objects as their physical manifestations. We locked down our data using Encapsulation, ensuring internal state cannot be corrupted. We utilized Inheritance to share common logic, and most importantly, we unlocked the immense power of Abstraction and Polymorphism. By programming to Interfaces rather than concrete classes, we create decoupled, flexible systems that are the absolute prerequisite for implementing advanced Design Patterns.

16. Next Chapter Recommendation

Now that we know the syntax of OOP, we must learn the philosophical rules of how to design classes so they don't turn into a tangled mess. Proceed to Chapter 3: SOLID Principles.

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: ·