1
The Essence of Python Object-Oriented Programming

2024-10-12

Classes and Objects

Do you understand the concepts of classes and objects? They're like "blueprints" and "entities" in real life.

Classes are abstract concepts that define the attributes and behaviors of a type of thing. They're like house blueprints drawn by architects, containing information such as the number of rooms, layout, materials, etc. Objects, on the other hand, are specific instances created based on these blueprints, like actual houses built according to the blueprints.

Defining Classes

Defining a class is like drawing a blueprint. First, you need to determine what attributes and methods it has. Let's take a simple Student class as an example:

class Student:
    def __init__(self, name, age):
        self.name = name  # attribute
        self.age = age

    def greet(self):  # method
        print(f"Hello, my name is {self.name}, and I'm {self.age} years old.")

Here we defined two attributes name and age, and one method greet(). Note that self represents the object itself, allowing methods to access the object's attributes.

Creating Objects

Once we have the class definition, we can create specific objects based on it, just like building houses:

stu1 = Student("Xiao Ming", 18)
stu2 = Student("Xiao Hong", 17)

We created two Student objects, each with different name and age attributes. You can call the object's method like this:

stu1.greet()  # Output: Hello, my name is Xiao Ming, and I'm 18 years old.

Isn't it intuitive? A class is like a template, making it easy for you to create multiple similar but not identical instance objects.

Inheritance

Inheritance is an important concept in object-oriented programming. Suppose we have a Person class with attributes like name, age, and a greet() method. If we want to define a Student class, we can inherit from the Person class:

class Student(Person):
    def __init__(self, name, age, grade):
        super().__init__(name, age)  # Call parent class constructor
        self.grade = grade  # Add new grade attribute

    def study(self):  # Add new study() method
        print(f"{self.name} is studying, grade is {self.grade}.")

Through inheritance, the Student class automatically possesses all attributes and methods of the Person class. We only need to add the new grade attribute and study() method, without repeating the code for name, age, and greet().

This approach maximizes code reuse, embodying the ideas of "coding" and "abstract modeling".

Polymorphism

Polymorphism refers to different objects responding to or behaving differently to the same method. Let's continue with the Student and Person example:

p = Person("Xiao Wang", 25)
s = Student("Xiao Li", 15, "First year of high school")

p.greet()  # Hello, my name is Xiao Wang, and I'm 25 years old.
s.greet()  # Hello, my name is Xiao Li, and I'm 15 years old.

Although the greet() method comes from the same Person class, its output is different for Person objects and Student objects. This is the manifestation of polymorphism - the same operation acting on different objects can produce different interpretations and execution results.

Polymorphism increases the flexibility of programs and is an important component of object-oriented design. Through polymorphism, we only need to focus on the behavior of objects, without worrying about their exact types.

Encapsulation

Encapsulation is another core principle of object-oriented programming. It stipulates that an object's internal attributes can only be accessed through the object's public methods, not directly. This protects the integrity of the object and prevents attributes from being modified to inconsistent or incorrect values.

class Student:
    def __init__(self, name, age):
        self.__name = name  # Adding __ in front makes the attribute private
        self.__age = age

    def get_age(self):
        return self.__age

    def set_age(self, new_age):
        if new_age < 0:
            print("Age cannot be negative")
        else:
            self.__age = new_age

stu = Student("Xiao Ming", 18)
print(stu.get_age())  # 18
stu.set_age(20)  # Modify age attribute
print(stu.get_age())  # 20

In this example, __name and __age are private attributes that can only be accessed and modified through the get_age() and set_age() methods. set_age() also includes an age validity check to ensure the input value is reasonable.

Encapsulation makes the code more robust and secure, and also facilitates later modification and maintenance. As a user, you only need to focus on the public interface provided by the object, without worrying about the internal implementation details.

In conclusion, object-oriented programming provides us with a way of thinking about abstract modeling, making code more flexible and extensible. By mastering core concepts such as classes, objects, inheritance, polymorphism, and encapsulation, you can write high-quality, maintainable Python programs. I hope this blog helps you better understand and apply object-oriented programming!