Skip to main content

Python

Python OOP: Classes, Inheritance, Polymorphism

·

Diagram showing a Python class hierarchy with Car as the base class and subclasses inheriting attributes and methods

Python is a multi-paradigm language that supports structured, object-oriented, and functional programming. This post covers the object-oriented paradigm: how classes, objects, inheritance, encapsulation, and special methods work in Python.

Need to submit an OOP assignment? Python assignment help connects you with a developer who writes and explains the code in your Python version.

Classes and objects

An object bundles state and behavior together. State lives in variables called attributes; behavior lives in functions called methods.

A car object, for example, carries attributes like brand, doors, and fuel_type, plus methods like start() and stop(). The exact combination depends on what the program needs to model.

A class is the template from which objects are created. It defines which attributes and methods every instance will have. In the real world, every car on the road belongs to the same class of things called "car", yet each individual car is a distinct object.

Python defines a class with the class keyword, a name, a colon, and an indented body. A string at the top of the body becomes the class docstring.

class Car:
    """Abstraction of a car object."""

    def __init__(self, gasoline):
        self.gasoline = gasoline
        print("Filled", gasoline, "litres")

    def start(self):
        if self.gasoline > 0:
            print("Engine started")
        else:
            print("Out of fuel -- cannot start")

    def drive(self):
        if self.gasoline > 0:
            self.gasoline -= 1
            print("Remaining fuel:", self.gasoline, "litres")
        else:
            print("Out of fuel -- cannot drive")

The __init__ method (double underscores on both sides) runs immediately after a new object is created. It handles any initialization the object needs.

Every instance method takes self as its first parameter. self refers to the current object and lets you distinguish between a local variable my_var and an object attribute self.my_var. Python passes self automatically when you call a method on an instance.

To create an object, call the class name with any arguments __init__ expects (excluding self):

my_car = Car(3)

Python passes the new object as the first argument. You supply only the remaining parameters (here, 3 for gasoline).

Access attributes and call methods with dot notation:

>>> print(my_car.gasoline)
3
>>> my_car.start()
Engine started
>>> my_car.drive()
Remaining fuel: 2 litres
>>> my_car.drive()
Remaining fuel: 1 litres
>>> my_car.drive()
Remaining fuel: 0 litres
>>> my_car.drive()
Out of fuel -- cannot drive
>>> my_car.start()
Out of fuel -- cannot start
>>> print(my_car.gasoline)
0

Everything in Python is an object. Strings, for example, expose methods like upper() and count(sub) for exactly this reason.

Inheritance

Three concepts underpin object-oriented programming: encapsulation, inheritance, and polymorphism. Inheritance comes first because it shapes the others.

When a class (the subclass) inherits from another class (the superclass), the subclass gains every attribute and method the superclass defined. Inheritance is also called "extending" a class.

Consider modeling instruments in a band: guitar, drums, bass. Each has unique details, but all share a common set of attributes and methods such as play(). The clean approach is one Instrument base class that holds the shared behavior, then Guitar, Battery, and Bass inherit from it.

To declare inheritance, list the parent class name in parentheses after the subclass name:

class Instrument:
    def __init__(self, price):
        self.price = price

    def play(self):
        print("Playing music")

    def break_instrument(self):
        print("That will cost you", self.price, "dollars")


class Battery(Instrument):
    pass


class Guitar(Instrument):
    pass

Battery and Guitar inherit play(), break_instrument(), and the price attribute from Instrument.

To add subclass-specific behavior, write a new __init__ in the subclass. It overrides the parent's. When you still need the parent's initialization to run, call it explicitly:

Instrument.__init__(self, price)

Notice that you must pass self when calling a parent method this way.

Multiple inheritance

Python allows a class to inherit from more than one parent at once. A Crocodile, for example, could inherit from both Land and Water classes:

class Land:
    def move(self):
        print("The animal walks")


class Water:
    def move(self):
        print("The animal swims")


class Crocodile(Land, Water):
    pass


c = Crocodile()
c.move()

When two parent classes define the same method, Python picks the one from the class listed furthest to the left in the inheritance declaration. Here Land is first, so c.move() prints "The animal walks".

Java and C# do not permit multiple inheritance. Python does, with the MRO (method resolution order) determining which parent wins.

Polymorphism

Polymorphism means different classes of objects respond to the same method call. A Guitar and a Battery can both respond to play() even though their implementations differ. Because one of a derived class's objects is also a valid superclass object, anywhere a method expects an Instrument you can pass a Guitar instead.

Python's dynamic typing makes this natural. Python does not restrict what type a function parameter can be; the only requirement is that the object supports whatever attributes and methods the function calls. This is sometimes called duck typing.

Method overloading (multiple methods with the same name but different parameter signatures) does not exist in Python. The last definition of a method name wins. You get similar behavior through default parameter values, *args, or **kwargs.

For a side-by-side comparison of Python and statically typed languages on this point, see inheritance vs. composition.

Encapsulation

Encapsulation controls which parts of an object are visible from outside the class.

Java uses public and private access modifiers. Python uses naming conventions instead. An attribute or method whose name starts with two underscores (and does not end with two underscores) is treated as private. Python renames it internally by prepending the class name, so __day inside class Date becomes _Date__day. The attribute still exists; it is just harder to reach by accident.

class Example:
    def public(self):
        print("Public")

    def __private(self):
        print("Private")


eg = Example()
eg.public()       # works
eg.__private()    # raises AttributeError

The name-mangled version is still accessible if you know the pattern:

eg._Example__private()

Getters and setters

When you want controlled access to a private attribute, write explicit getter and setter methods:

class Date:
    def __init__(self):
        self.__day = 1

    def get_day(self):
        return self.__day

    def set_day(self, day):
        if 0 < day < 31:
            self.__day = day
        else:
            print("Invalid day")


my_date = Date()
my_date.set_day(33)  # prints "Invalid day"

Properties

Python's property() function wraps getters and setters so callers use attribute syntax rather than method calls:

class Date(object):
    def __init__(self):
        self.__day = 1

    def get_day(self):
        return self.__day

    def set_day(self, day):
        if 0 < day < 31:
            self.__day = day
        else:
            print("Invalid day")

    day = property(get_day, set_day)


my_date = Date()
my_date.day = 33  # triggers set_day, prints "Invalid day"

New-style classes

The example above inherits from object. This makes Date a "new-style" class, a model introduced in Python 2.2 and made universal in Python 3. New-style classes are required for property() to work. In Python 3, all classes are new-style automatically; you do not need to write (object) explicitly. The convention remains common in code that once had to support Python 2.

Special methods

Python calls certain methods automatically under specific conditions. Their names always begin and end with double underscores.

__init__(self, args) Runs after the object is created. Handles initialization.

__new__(cls, args) Runs before __init__. Constructs and returns the new object. A static method: the first parameter is the class itself (cls), not the instance. Available only on new-style classes.

__del__(self) Runs when the object is about to be garbage-collected. Use for cleanup.

__str__(self) Returns a human-readable string for the object. Called by print() and str(obj).

__cmp__(self, other) Called when comparison operators (<, <=, >, >=) are used. Return a negative number if self is less than other, zero if equal, positive if greater. Python 3 replaces this with the six rich comparison methods (__lt__, __le__, __eq__, __ne__, __gt__, __ge__).

__len__(self) Returns the object's length. Called by len(obj).

Python also supports special methods for slicing, arithmetic operators, dictionary syntax, and iteration. The official Python documentation covers the full list.

Where to go next

The patterns here (classes, inheritance, properties, dunder methods) show up in every substantial Python project. Introduction to Python builds the foundations this post assumes. If you are working on an OOP assignment and need a working solution with a walkthrough, Python assignment help is available for same-day delivery.

Share: X / Twitter LinkedIn

Related articles

  • Machine Learning

    Build a Movie Recommendation System in Python

    Build a movie recommender in Python with content-based filtering, collaborative filtering, and a hybrid model, then evaluate it and ship it with Flask.

    Jan 27, 2025

  • Programming

    How to Become a Python Developer

    A step-by-step roadmap covering core Python concepts, libraries, frameworks, databases, testing, DevOps, and interview prep for aspiring Python developers.

    Oct 26, 2024

  • Python

    Efficient Python Algorithms Explained

    Sorting, searching, dynamic programming, greedy methods, and string algorithms in Python, with Big O analysis and working code for each.

    Mar 22, 2024

← All articles

Stuck on a programming assignment?

Get expert help in Java, C++, Python, JavaScript, SQL, and more. We deliver working code with a clear walkthrough so you can understand and defend it.