Nesting Classes/Functions

Python Polymorphism

Python Sub-Classes

Python Class Inheritance

Python Metaclasses



Introduction

Python is a popular programming language known for its simplicity and versatility. One of the most important concepts in Python programming is classes. Classes allow you to create your own custom data types and encapsulate methods and attributes within them. This makes it easier to organize and manage large codebases and create complex systems.

Defining a Class

In Python, you define a class using the class keyword, followed by the name of the class and a colon. The body of the class contains the various methods and attributes that define the behavior of the class. For example, let's say we want to create a class to represent a car. We can define the class like this:

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def start_engine(self):
        print(f"{self.make} {self.model} engine started.")

    def stop_engine(self):
        print(f"{self.make} {self.model} engine stopped.")

This class has three attributes (make, model, and year) and two methods (start_engine and stop_engine). The __init__ method is a special method that is called when a new instance of the class is created. It initializes the attributes of the class with the values passed in as arguments.

Creating an Instance of a Class

To create a new instance of the class, we simply call the class like a function, passing in the necessary arguments:

my_car = Car("Toyota", "Corolla", 2021)

Now we can call the methods of the class on our new instance:

my_car.start_engine() # prints "Toyota Corolla engine started."
my_car.stop_engine() # prints "Toyota Corolla engine stopped."

Inheritance

One of the most powerful features of classes is inheritance. Inheritance allows you to create new classes that are based on existing classes, inheriting their attributes and methods. This allows you to reuse code and create more specialized classes without duplicating code. For example, let's say we want to create a new class SportsCar that inherits from Car:

class SportsCar(Car):
    def __init__(self, make, model, year, top_speed):
        super().__init__(make, model, year)
        self.top_speed = top_speed

    def go_fast(self):
        print(f"{self.make} {self.model} going {self.top_speed} MPH!")

This new class has all the attributes and methods of Car, as well as its own attribute top_speed and method go_fast. We can create a new instance of SportsCar just like we did with Car: