Understanding object-oriented programming

preface

The article resources for reference are http://www.coolpython.net/python_primary/oop/polymorphism.html
Object Oriented Programming -- Object Oriented Programming, referred to as OOP. Another corresponding programming idea is process oriented programming.
OOP comes from nature. In nature, we know classes and examples, such as reptiles, mammals, insects and so on. There is also a primate under mammals. And we humans are primates. Everyone is an example of human beings.

The three core characteristics of object-oriented are: encapsulation + inheritance + polymorphism

Class definition and instantiation

Class definition

Because python is also an object-oriented programming language. So there is also the concept of class. Provides all standard properties facing objects. For example, a class is allowed to inherit multiple base classes. Subclasses can override the methods of the parent class, and so on.

Use class to define a class

class Stu:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def run(self):
        print("{name} is running".format(name=self.name))

understand:
(1) Stu above is the name of the class. You can use__ name__ To visit

print(Stu.__name__)
Output:
Stu

(2) In the class, use the def keyword to define the function. But in the class, we call this function a method. It is called instance method.
(3)__ init__ Is an initialization function. When the instance is constructed, use__ init__ Method to initialize instance properties. Self is an instance, and name and age are attributes of the instance. Let's see why self is an example.

s = Stu('Xiao Ming', 18)
s.run()
Output:<class '__main__.Stu'>
Xiao Ming is running

Here we see that s is the created instance. That is, the previously set self.
When initializing the function, there are two attributes: name and age. Because when we create an instance, we must enter these two parameters, here 'Xiaoming', 18.
s.run() is calling the run method of the instance.
To sum up, we created the two attributes name and age of the instance above; The run method of the instance is also defined.
Therefore, instances have corresponding methods and properties.

(4) Modify the properties of the object

class Stu:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print("{name}this year{age}year".format(name=self.name, age=self.age))

    def run(self):
        print("{name} is running".format(name=self.name))

    def print(self):
        print("ok")

s = Stu("Xiao Gang", 18)
s.info()

print(s.name)
s.age = 20
s.info()

Output:
Xiao Gang is 18 years old
 Xiao Gang
 Xiao Gang is 20 years old

(5) Use classes to combine data and methods
Use an example to illustrate:
The student's test scores are saved in a file called transcript, which is as follows

Name Chinese mathematics English
 Xiaohong ninety 95    90
 Xiao Gang 91 94    ninety-three

Write a program to read the file, save these data with appropriate data types, output each subject and score of each person, and calculate the total score of each student.

For object-oriented programming, write as follows:

stus = []
with open('school report', 'r', encoding='utf-8') as file:
    lines = file.readlines()
    for i in range(1, len(lines)):
        line = lines[i]
        arrs = line.split()
        stus.append(arrs)
for stu in stus:
    msg = "{name}The results of each subject are as follows: language:{yw_score}, " \
          "mathematics:{sx_score}, English:{en_score}".format(name=stu[0],
                                                yw_score=stu[1],
                                                sx_score=stu[2],
                                                en_score = stu[3]
                                                )
    print(msg)
    msg = "{name}The total score is{socre}".format(name=stu[0],
                                      socre=int(stu[1])+int(stu[2])+int(stu[3]))

    print(msg)

However, if object-oriented programming is used, it is written as:

class Stu:
    def __init__(self, name, yw, sx, en):
        self.name = name
        self.yw = yw
        self.sx = sx
        self.en = en

    def score_sum(self):
        return self.yw + self.sx + self.en

    def print_score(self):
        msg = "{name}The results of each subject are as follows: language:{yw_score}, " \
          "mathematics:{sx_score}, English:{en_score}".format(name=self.name,
                                                yw_score = self.yw,
                                                sx_score = self.sx,
                                                en_score = self.en
                                                )
        print(msg)
        msg = "{name}The total score is{score}".format(name=self.name, score=self.score_sum())
        print(msg)

stus = []
with open('school report', 'r', encoding='utf-8') as file:
    lines = file.readlines()
    for i in range(1, len(lines)):
        line = lines[i]
        arrs = line.split()
        s = Stu(arrs[0], int(arrs[1]), int(arrs[2]), int(arrs[3]))
        stus.append(s)
for stu in stus:
    stu.print_score()

From the perspective of code readability, using classes to organize data and methods is obviously more advantageous. Moreover, the concept of classes is more in line with our human thinking.
Using classes to organize data and methods has better scalability. New attributes and methods can be added at any time. For example, if I want to output the highest subject score of students, I just need to modify the class.
However, the programming facing the process needs a lot of modification, and the maintainability is very poor.

Class encapsulation

Hide the details of the implementation and only disclose the properties and methods we want them to use. This is called encapsulation.
The purpose of encapsulation is to protect the integrity of the internal data structure of the class, because users using the class can not directly see the data structure in the class, and can only use the data allowed to be exposed by the class, which well avoids the external impact on the internal data and improves the maintainability of the program.

(1) Private properties and methods

Suppose you and your colleagues do projects together, and now you need to write a class for colleagues to use. You define 5 attributes and 10 methods, but your colleagues will only use one of them. The remaining 9 are the methods used in the execution process.

Then, when the problem comes, tell him clearly that you can call the a method. Don't use other methods, otherwise the result may be affected. If your colleague is a very self-contained person, he listens to your advice and honestly calls method A. he doesn't move any other methods. This is safe.

But after a few days, a new colleague came. He was disobedient and had to call the remaining nine methods. It felt that calling the nine methods could better realize the functions. As a result, there was a big problem. He didn't use the nine methods well, resulting in program errors.

We write a class with some properties and methods that we don't want to be used by others, because it is easy to produce errors. At this time, we need to hide the implementation details and only disclose the properties and methods we want them to use. This is called encapsulation. It's like packing something in a box with only one opening, so you can't see it inside

How can this be done?

In python, if a property or method is preceded by a double underscore, the property or method becomes a private property. Here is an example.

class Animal:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def __run(self):
        print("run")

a = Animal('cat', 2)
a.__run()
print(a.__name, a.__age)

This will cause errors. You can't use the method of run and the two properties of name and age.
Another problem is that if the age is set to 10000, it is obviously wrong. Therefore, such methods are also set in the class to avoid this situation.

class Animal:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def set_age(self, age):
        if age > 100 or age < 1:
            raise Exception("Wrong age range")
        self.__age = age

    def get_age(self):
        return self.__age

    def __run(self):
        print("run")

a = Animal('cat', 2)
a.set_age(3)
print(a.get_age())

inherit

Inheritance is a way to create new classes. Inheritance in python can inherit one or more parent classes. The new class is called derived class or child class, and the inherited class is the parent class.

(1) Single inheritance

class Car(object):
	def __init__(self, speed,brand):
		self.speed = speed
		self.brand = brand
	def run(self):
		print("{brand}Driving".format(brand = self.brand))
# Fuel truck
class Gasolinecar(Car):
	def __init__(self,speed,brand,price):
		super().__init__(speed,brand)
		self.price = price

class Audi(Gasolinecar):
	pass

honda = Gasolinecar(130,'Honda', 13000)
honda.run()

audi_car = Audi(100,'audi',10000)
audi_car.run()

Output:
Honda is driving
 Audi is driving

Inheritance means that a subclass is about to have the methods and properties of its parent class. At the same time, add the attributes and methods of subclasses.
In the Gasolinecar class, I did not write the run method, but the parent class of Gasolinecar defines the run method. Therefore, Gasolinecar also has this method, so the object honda of this class can use the run method.

The Audi class does not define any method, but it inherits Gasolinecar. Therefore, it owns all the properties and methods of Gasolinecar, which are included here__ init__ method.

super() can be used to call the method of the parent class. Gasolinecar passes an extra price attribute, and its parent class__ init__ Method has two parameters, so you can call the parent class first__ init__ Method initializes speed and brand, and then initializes price.

polymorphic

(1) Rewrite
The concept of polymorphism depends on inheritance, because inheritance makes the subclass have the method of the parent class. Here, a problem arises. If a subclass has a method with the same name as the method of the parent class, when calling this method, does the subclass call its own method or the method of the parent class?

class Base():
    def print(self):
        print("base")


class A(Base):
    def print(self):
        print("A")


a = A()
a.print()
Output:
A

Both parent and child classes have print methods. When object a of child class a calls the print method, whose print method is called?

The answer is the print method of the subclass. If class A does not define the print method, then a.print() calls the print method of the parent class, but class a defines the print method. This is called rewriting. Class a rewrites the print method of the parent class

(2) Manifestations of polymorphism

class Animal:
    def run(self):
        raise NotImplementedError

class People(Animal):
    def run(self):
        print("People are walking")


class Pig(Animal):
    def run(self):
        print("The pig is running")


p1 = People()
p1.run()

p2 = Pig()
p2.run()

Output:
People are walking
 The pig is running

People and Pig inherit Animal. They are both animals and the same kind of things. They both have run methods, but the final running results are different. This is polymorphism. The same kind of things have multiple forms

Keywords: Python Programming

Added by devarmagan on Sat, 22 Jan 2022 03:55:17 +0200