Object-Oriented Programming
Classes, inheritance, polymorphism and class design in Java, C++ or Python.
Object-oriented programming is easier when every idea is shown on the same example. We build a small library system step by step and name each OOP concept as it appears.
By Ali Sher AbbasiPublished 4 min read
Object-oriented programming (OOP) is a way of organising code around things rather than around steps. Instead of one long list of instructions, you describe the things in your program (a book, a member, a loan), what each one knows, and what each one can do. Most OOP courses list four "pillars": encapsulation, inheritance, polymorphism and abstraction. They make far more sense when you see them solve real problems in one program, so that is what we will do.
The examples are in Python because it is short to read. The same ideas apply in Java and C++, and we point out the differences as we go.
A class is a blueprint. An object is one thing built from that blueprint. A library has one idea of what a book is (the class) and thousands of actual books (objects).
class Book:
def __init__(self, title, author):
self.title = title # data each book carries
self.author = author
self.on_loan = False
def describe(self): # something each book can do
return f"{self.title} by {self.author}"
first = Book("Clean Code", "Robert C. Martin")
second = Book("Python Crash Course", "Eric Matthes")
print(first.describe())__init__ is the constructor: it runs once when each object is created and gives it its starting data. first and second are two separate objects with their own title, author and on_loan values.
Right now any part of the program can write first.on_loan = True without checking anything, including lending a book that is already out. Encapsulation means keeping the data inside the object and only changing it through methods that enforce the rules.
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
self._on_loan = False # "internal": change it through methods
def lend(self):
if self._on_loan:
raise ValueError(f"{self.title} is already on loan")
self._on_loan = True
def give_back(self):
self._on_loan = False
@property
def available(self):
return not self._on_loanNow there is exactly one place where a loan can happen, and it checks the rule every time. In Python the underscore is a convention that says "do not touch this from outside". Java and C++ enforce it with the private keyword, and the compiler refuses code that breaks the rule.
The library also lends DVDs. A DVD has a title and can be lent and returned, just like a book, but it has a running time instead of an author. Inheritance lets a new class reuse an existing one and add or change only what is different.
class Item:
loan_days = 14
def __init__(self, title):
self.title = title
self._on_loan = False
def lend(self):
if self._on_loan:
raise ValueError(f"{self.title} is already on loan")
self._on_loan = True
def describe(self):
return self.title
class Book(Item):
def __init__(self, title, author):
super().__init__(title) # let Item set up the shared parts
self.author = author
def describe(self):
return f"{self.title} by {self.author}"
class Dvd(Item):
loan_days = 7
def __init__(self, title, minutes):
super().__init__(title)
self.minutes = minutes
def describe(self):
return f"{self.title} ({self.minutes} min)"Book and Dvd both inherit lend from Item, so the loan rule is written once. Dvd also overrides loan_days, because DVDs go back sooner. The test for inheritance is the phrase "is a": a book is an item, and a DVD is an item.
Polymorphism means "many forms": the same method call does the right thing for each kind of object. The code that prints the catalogue does not need to know whether it is holding a book or a DVD.
catalogue = [
Book("Clean Code", "Robert C. Martin"),
Dvd("Planet Earth II", 298),
]
for item in catalogue:
print(item.describe(), "-", item.loan_days, "days")
# Clean Code by Robert C. Martin - 14 days
# Planet Earth II (298 min) - 7 daysWhen the library adds magazines, you write a Magazine class with its own describe, and this loop works without a single change. That is the practical value of polymorphism: new kinds of objects fit into old code.
Abstraction means exposing a simple interface and hiding the details. A librarian calls item.lend() without knowing how loans are stored. You can go further and make Item an abstract class: one that cannot be created on its own and that requires every subclass to provide certain methods.
from abc import ABC, abstractmethod
class Item(ABC):
# ... the same shared code as before ...
@abstractmethod
def describe(self):
"""Every kind of item must say how it is described."""
Item("Mystery") # TypeError: Can't instantiate abstract class Item ...In Java this is an abstract class or an interface; in C++ it is a class with a pure virtual function (virtual std::string describe() = 0;).
Magazine class with an issue number and a three-day loan.Member class that can borrow at most three items at once. Where should that rule live?Item and Book in Java with private fields and getters.If you would like someone to review your answers, or you are preparing for an OOP exam or a university project in Java, C++ or Python, our OOP tutoring is one-to-one and starts with a free class. When OOP feels comfortable, data structures and algorithms is the natural next step.
One-to-one live classes on this topic. The first class is free.
Classes, inheritance, polymorphism and class design in Java, C++ or Python.
Python fundamentals, C and C++, Java, and JavaScript with web development, taught one-to-one.
Complexity, lists, trees, graphs, sorting and dynamic programming, implemented step by step.
Your first language matters less than you think, but the right one for your goal saves weeks of frustration. Here is how to choose, by what you want to do next.
4 min read
Data Structures and Algorithms feels huge until you learn it in the right order. Here is what to know first, a topic sequence that builds on itself, and a way to practise that works.
4 min read
Cybersecurity is a huge field, and most beginners start with tools instead of foundations. This roadmap gives you an order that builds real understanding, and shows how to practise without breaking the law.
4 min read