Three characteristics of object-oriented languages: encapsulation inheritance polymorphism (1)-encapsulation

1. What is packaging?

In a program, encapsulation is an abstraction of concrete objects.

Simply put: hide some parts (privatization), other parts of the program are invisible (there is no way to call directly)

Privatization: privatize features or some methods in the class, making it impossible to directly use externally

2. The benefits of packaging

  • Protect privacy — hide the parts that you don’t want the outside world to know
  • Isolate the complexity ----- hide the complex implementation in the program -> provide a simple interface [method] to use the private content
  • Improve the robustness of the code
  • Add necessary judgments according to actual needs

3. How to package

  • Generally, the attribute is privatized, and the corresponding set and get methods are provided for the attribute
  • Add two underscores before the property name to privatize

Why privatize?

  • Can be called directly or modified at will
  • After modification, it does not meet the needs of real life -> bug -> can not be modified at will
  • Simply put, it is to add a condition before the modification, and then let you modify the condition when the condition is met.
class Student:
    def __init__(self, name, age, sex):
        self.name = name
        # self.age = age
        self.__age = age  # 加两个下划线私有化
        self.sex = sex


def main():
    stu = Student("诡途", 18, '男')
    print(stu.name)
    # print(stu.age)
    # print(stu.__age)

    # 也可以在外部进行随意的修改
    stu.age = -10  # 不满足实际生活需求-->bug-->不能让外界随意修改
    print(stu.age)


if __name__ == '__main__':
    main()

After privatization, it cannot be called through attributes, nor can it be modified! But it needs to be called and modified.
Therefore, it is necessary to provide a simple interface for obtaining

  • Provide an interface for assignment:

    • The assignment is performed by the outside world, and the value is passed in when it needs to be called from the outside. The assignment interface needs to have a formal parameter
    • Pseudo code of assignment method
    def set_字段名(self, 代表字段名的形参):
    	if 条件:
    		self.__字段名 = ??
    	elif 条件:
    		self.__字段名 = ??
    	else:
    		self.__字段名 = 代表字段名的形参 #(或者是在if|elif下,根据实际需求写)
    
  • Provide the value interface:

    • The outside world only wants to get the value of this field, and does not want to pass the value, the interface for the value needs to have a return value
    • Pseudo code of the value method
    #伪代码
    def get_字段名(self):
    	return self.__字段名
    

Private package complete code

class Student:
    def __init__(self, name, age, sex):
        self.name = name
        # self.__age = age
        # 因为初始化时,也是由外界赋值的,
        # 所以在初始化时,也需要判定数据的合理性,再进行赋值
        # 因为判断数据合理性已经封装成方法了,所以直接调用赋值方法即可
        self.set_age(age)
        self.sex = sex

    def set_age(self, age):
        # 可以按照实际生活需求加入逻辑判断
        if age < 0:
            # 设置默认值
            self.__age = 0
        else:
            self.__age = age

    def get_age(self):
        return self.__age


def main():
    stu = Student("诡途", 18, '男')
    stu_age = stu.get_age()
    print(stu_age)

    # 调用设置的接口
    stu.set_age(-10)
    stu_age = stu.get_age()
    print(stu_age)

    # 对象的特征值是动态赋予的


if __name__ == '__main__':
    main()

set and get do not necessarily appear in pairs, write as needed

4. Attributed get and set methods

  • Attributed----> It can be called as if it has not been encapsulated when it is called outside
  • Property call: object. Property name
  • Method call: object. method name ()
  • After the get and set methods are attributed — the format of calling them is similar to that of directly calling attributes

How to attribute it?

  • The way to attribute the get method----> a decorator provided by the system @property
  • Attributed the set method ----> A setter decorator created on the basis of the attributed get method -> Attributed the set method -> Format: @getmethod name.setter

[For details about decorators, see] The artifact that modifies the functions of other functions-python decorator

Code sample

class Person:
    def __init__(self, name, age, sex):
        # 这些特征称之为对象的属性
        self.name = name
        self.age = age
        # self.set_sex(sex)

        # 属性化后,要按照属性的方式进行赋值
        # self.set_sex = sex

        # 修改方法名
        self.sex = sex
    #
    # @property
    # def get_sex(self):
    #     return self.__sex

    @property
    def sex(self):
        return self.__sex

    # @get_sex.setter
    # def set_sex(self, sex):
    #     if sex != "男" and sex != "女":
    #         self.__sex = "男"
    #     else:
    #         self.__sex = sex

    @sex.setter
    def sex(self, sex):
        if sex != "男" and sex != "女":
            self.__sex = "男"
        else:
            self.__sex = sex


# 在类的外部获取对象的属性
p = Person("诡途", 18, "男")

# 获取属性的方式: 对象.属性名
print(p.name)

# # 直接调用get方法
# value = p.get_sex()
# print(value)

# 属性化之后调用  --》只能通过属性化的方式来调用
# value = p.get_sex  # 属性化之后 等价于 get_sex()() 等价于 "男"()  ==》报错TypeError: 'str' object is not callable
# print(value)

# 属性化之后,把对属性的修改映射回,封装之前那样对属性进行修改或者获取

# 对于正常的属性进行赋值
p.name = "图图"

# 对私有化属性进行赋值
# p.set_sex("女")


# # 属性话后进行赋值
# p.set_sex = "女"
# print(p.get_sex)


p.sex = "女"
print(p.sex)

Because the general field name is not modified by set and get, generally when naming the get method and set method, they are directly named as the field name

Guess you like

Origin blog.csdn.net/qq_35866846/article/details/108224333