• 面向对象编程 09


    01面向对象编程介绍

    """
    1、面向过程编程
        核心是“过程”二字,过程指的是做事的步骤
        基于该思想编写程序就好比在设计一条条的流水线
    
        优点:复杂的问题流程化、进而简单化
        缺点:扩展性差
    
    2、面向对象编程
        核心是“对象”二字,对象是一个的容器(盛放相关的数据与功能)
        基于该思想编写程序就是造一个个对象/容器
    
        优点:扩展性强
        缺点:比起面向过程来说,加重了编程的复杂度
    
    大白话:面向对象编程的核心就是造对象/容器盛东西,该容器就是一个内存空间
    """
    
    def choose(self):
        print('<%s:%s:%s>正在选课' %(self["stu1_name"],self["stu1_age"],self["stu1_gender"]))
    
    Student_dic={
    "school":"oldboy",
    "choose":choose
    }
    
    stu1_dic={
    
        "stu1_name":"egon",
        "stu1_age":18,
        "stu1_gender":"male",
    
    }
    
    stu2_dic={
        "stu1_name":"jack",
        "stu1_age":19,
        "stu1_gender":"female",
    }
    
    # print(stu1_dic)
    # stu1_dic["choose"](stu1_dic)
    # print(stu1_dic["stu1_name"])
    面向对象编程介绍

    02类与对象

    # 什么是类?
    #   类就是一个容器(一个内存空间),存放的是对象之间相同的数据与功能
    # 为何要有类?
    #   为了节省内存空间
    
    """
    学生对象1
        数据
            学校="oldboy"
            名字="张三"
            年龄=18
            性别="male"
        功能
            选课功能
    
    学生对象2
        数据
            学校="oldboy"
            名字="李四"
            年龄=19
            性别="female"
        功能
            选课功能
    
    学生对象3
        数据
            学校="oldboy"
            名字="王五"
            年龄=23
            性别="male"
        功能
            选课功能
    
    学生类
        相同数据
            学校="oldboy"
        相同功能
            选课功能
    """
    
    #语法规定:先定义类,后调用类产生对象
    class Student:
        # 相同数据
        school ="oldboy"
    
        # 相同功能
        def choose(self):
            print('is choosing course')
    
        # print("====>")
    
    # 1、定义类=》把存有所有学生对象相同的数据与功能的内存空间准备好
    # 类体代码会在类定义阶段立即运行,所以会产生一个类的名称空间,将类体代码运行过程中
    # 产生的名字都丢到类的名称空间中,然后类名指向的就是类的名称空间
    # print(Student.__dict__)
    # print(Student.school)  # Student.__dict__["school"]
    
    # 2、调用类=》产生对象
    # 调用类做的事情
    # (1)造一个对象的内存空间,并将给内存空间与类的内存空间绑定
    stu_obj1 = Student()
    stu_obj2 = Student()
    stu_obj3 = Student()
    
    # print(stu_obj1)
    # print(stu_obj2)
    # print(stu_obj3)
    
    # print(stu_obj1.__dict__)
    # print(stu_obj2.__dict__)
    # print(stu_obj3.__dict__)
    # print(stu_obj1.school)
    
    # 3、为对象初始化自己独有的属性
    stu_obj1.name = "张三"  # stu_obj1.__dict__["name"]="张三"
    stu_obj1.age = 18  # stu_obj1.__dict__["age"]=18
    stu_obj1.gender = "male"  # stu_obj1.__dict__["gender"]="male"
    # print(stu_obj1.__dict__)
    
    stu_obj2.name = "李四"
    stu_obj2.age = 19
    stu_obj2.gender = "female"
    
    stu_obj3.name = "王五"
    stu_obj3.age = 23
    stu_obj3.gender = "male"
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    # print(stu_obj1.name)
    # print(stu_obj1.age)
    # print(stu_obj1.gender)
    #
    # print(stu_obj1.school)
    # print(stu_obj1.choose)
    
    # stu_obj2
    # stu_obj3
    类与对象

    03__init__方法

    # class Student:
    #     school ="oldboy"
    #
    #     def choose(self):
    #         print('is choosing course')
    #
    # stu_obj1 = Student()
    # stu_obj2 = Student()
    # stu_obj3 = Student()
    
    
    # 为对象初始化自己独有的属性
    # stu_obj1.name = "张三"  # stu_obj1.__dict__["name"]="张三"
    # stu_obj1.age = 18  # stu_obj1.__dict__["age"]=18
    # stu_obj1.gender = "male"  # stu_obj1.__dict__["gender"]="male"
    
    # stu_obj2.name = "李四"
    # stu_obj2.age = 19
    # stu_obj2.gender = "female"
    
    # stu_obj3.name = "王五"
    # stu_obj3.age = 23
    # stu_obj3.gender = "male"
    
    # 优化方案1:
    # def init(obj,name,age,gender):
    #     obj.name = name
    #     obj.age = age
    #     obj.gender = gender
    
    # init(stu_obj1, "张三" ,18,"male")
    # init(stu_obj2, "李四" ,19,"female")
    # init(stu_obj3, "王五" ,23,"male")
    
    # print(stu_obj1.__dict__)
    # print(stu_obj2.__dict__)
    # print(stu_obj3.__dict__)
    
    # 终极解决方案:
    class Student:
        school ="oldboy"
        #            空对象,"张三",18,"male"
        def __init__(obj, name, age, gender):
            obj.name = name  # 空对象.name = "张三"
            obj.age = age  # 空对象.age = 18
            obj.gender = gender  # 空对象.gender = "male"
            # return None  # 注意!!!:不能有返回值
    
        def choose(self):
            print('is choosing course')
    
    # 调用类发生的事情
    # 1、先造一个空对象(空对象的本质就是一个与类的内存空间相关联的、对象的内存空间)
    # 2、触发类中的__init__函数的运行,会将(空对象"张三" ,18,"male")一起传给__init__函数,完成为对象初始化属性的操作
    # 3、将初始化好属性的对象的内存地址赋值给等号左侧的变量名stu_obj1
    stu_obj1=Student("张三" ,18,"male")
    stu_obj2=Student("李四" ,19,"female")
    stu_obj3=Student("王五" ,23,"male")
    
    print(stu_obj1.__dict__)
    print(stu_obj2.__dict__)
    print(stu_obj3.__dict__)
    __init__

    04类与对象的属性操作

    class Student:
        school ="oldboy"
        n=0
    
        def __init__(obj, name, age, gender):
            Student.n+=1
            obj.name = name  # 空对象.name = "张三"
            obj.age = age  # 空对象.age = 18
            obj.gender = gender  # 空对象.gender = "male"
    
        def choose(self):
            print('is choosing course')
    
    
    stu_obj1=Student("张三" ,18,"male")
    stu_obj2=Student("李四" ,19,"female")
    stu_obj3=Student("王五" ,23,"male")
    
    print(Student.n)
    print(stu_obj1.n)
    print(stu_obj2.n)
    print(stu_obj3.n)
    # 一 类与对象属性操作
    # 1.对象的属性操作
    # (1) 访问
    # print(stu_obj1.name)
    # print(stu_obj1.school)
    
    # (2) 删除(只能清楚对象自己名称空间内的)
    # del stu_obj1.name
    # print(stu_obj1.__dict__)
    
    # (3)新增与修改
    # stu_obj1.x = 111
    # print(stu_obj1.__dict__)
    # stu_obj1.x = 222
    # print(stu_obj1.x)
    
    # 2.类的属性操作
    # (1) 访问
    # print(Student.school)
    # print(Student.choose)
    # (2) 删除(只能清楚类自己名称空间内的)
    # del Student.school
    # print(Student.__dict__)
    # (3)新增与修改
    # Student.xxx=111
    # Student.xxx=222
    # print(Student.__dict__)
    
    # !!!总结
    # 1、
    # 对象.属性:先从对象自己的内存空间找,没有则去类中查找
    # 类.属性:直接去类中查找
    # stu_obj1.school = "xxx"
    # print(stu_obj1.school)
    # print(stu_obj2.school)
    # print(stu_obj3.school)
    
    # 2、类中定义的属性类可以使用,但其实是为对象准备的
    # 类的数据属性是所有对象共享的
    # print(Student.school,id(Student.school))
    # Student.school="OLDBOY"
    # print(stu_obj1.school,id(stu_obj1.school))
    # print(stu_obj2.school,id(stu_obj2.school))
    # print(stu_obj3.school,id(stu_obj3.school))
    
    # 类的函数属性
    print(Student.choose)
    print(stu_obj1.choose)
    print(stu_obj2.choose)
    print(stu_obj3.choose)
    类与对象属性操作

    05绑定方法

    class Student:
        school ="oldboy"
    
        def __init__(self, name, age, gender):
            self.name = name  # 空对象.name = "张三"
            self.age = age  # 空对象.age = 18
            self.gender = gender  # 空对象.gender = "male"
    
        def choose(self):
            print('%s is choosing course' %self.name)
    
        def tell_info(self):
            print('<%s:%s:%s>' %(self.name,self.age,self.gender))
    
    stu_obj1=Student("张三" ,18,"male")
    stu_obj2=Student("李四" ,19,"female")
    stu_obj3=Student("王五" ,23,"male")
    stu_obj1.tell_info()
    stu_obj2.tell_info()
    stu_obj3.tell_info()
    # 类中定义的函数类可以访问,但是类来访问的时候就是一个普通函数,必须按照普通函数的玩法来
    # print(Student.choose)
    # Student.choose(stu_obj1)
    
    # print(stu_obj1.choose)
    # print(stu_obj2.choose)
    # print(stu_obj3.choose)
    
    # 类中定义的函数其实是给对象准备的,对象来用,称之为调用绑定方法
    # 绑定方法的特殊之处在于自动传参:会将调用者当作第一个参数自动传入
    # stu_obj1.choose() # choose(stu_obj1)
    # stu_obj2.choose() # choose(stu_obj2)
    # stu_obj3.choose() # choose(stu_obj2)
    
    
    
    # 在python3里统一了类与类型的概念
    # l1=[1,2,3]  # l1=list([1,2,3])
    # print(type(l1))
    # print(type(stu_obj1))
    # l2=[11,22]  # l1=list([1,2,3])
    
    # l1.append(333)
    # print(l1)
    # l2.append(444)
    # print(l2)
    
    # list.append(l1,333)
    # print(l1)
    # list.append(l2,444)
    # print(l2)
    绑定方法

    06三大特性之封装

    """
    1 什么是封装
        封装=》整合
    
    2 为何要封装
        为了让程序的整合程度更高,进而提升程序的解耦合程度
    
    3 如何封装
    
    3.1 把装到类或对象里的属性藏起来
    (1)藏起来就是:把装进去的属性隐藏起来不让类外部访问到
    (2)为何要将属性藏起来???
        1、把数据属性藏器里的目的是:严格控制类外部使用者对属性的操作
                不想让外部直接操作属性,通过开放接口的方式外部间接操作属性,
                我们可以在接口之上附加任意控制逻辑,从而严格控制类外部使用者对属性的操作
        2、把功能属性藏起来的目的是:为了隔离复杂度
    
    (3)如何藏起来
        在属性前加__开头,就会将该属性隐藏起来
    
        注意:
            (1) 这种不是真正意义上的隐藏,仅仅只是一种变形操作
            (2) 该变形操作只在类定义阶段检查语法的时候变形一次,在此之后,新增的__开头的属性
                    都不会发生变形
            (3) 该变形操作对外不内
    
    """
    # 应用
    class People:
        def __init__(self,name,age,gender):
            self.__name=name
            self.age=age
            self.gender=gender
    
        def get_name(self):
            print("名字:%s" %self.__name)
    
        def set_name(self,val):
            if type(val) is not str:
                print("名字必须是str类型")
                return
            self.__name = val
    
        def del_name(self):
            print('不让删除')
    
    p=People('egon',18,'male')
    # p.__name=123123123
    # print(p.name)
    
    # p.get_name()
    # p.set_name("EGON")
    p.del_name()
    
    
    
    # 示例
    
    class Foo:
        __x = 111  # _Foo__x = 111
    
        def __init__(self, m, n):
            self.__m = m  # self._Foo__m = m
            self.__n = n  # self._Foo__n = n
    
        def __f1(self):  # _Foo__f1
            print('from f1')
    
        def f2(self):  # self._Foo__m,self._Foo__n,self._Foo__x
            print(self.__m,self.__n,self.__x)
    
    # print(Foo.__x)
    # print(Foo.__f1)
    # print(Foo.__dict__)
    # print(Foo._Foo__x)
    # print(Foo._Foo__f1)
    
    # obj1=Foo(666,777)
    # print(obj1._Foo__x)
    # print(obj1._Foo__f1)
    
    # print(obj1.__dict__)
    # print(obj1._Foo__m)
    # print(obj1._Foo__n)
    
    # Foo.__zzz=1111
    # print(Foo.__dict__)
    # print(Foo.__zzz)
    
    # obj1=Foo(666,777)
    # obj1.__yyy=222
    # print(obj1.__dict__)
    #
    # obj1.f2()
    三大特性之封装

    07property装饰器

    #1、property的基本使用
    class People:
        def __init__(self, name, height, weight):
            self.name = name
            self.height = height
            self.weight = weight
    
        @property
        def bmi(self):
            return self.weight / (self.height ** 2)
    
    p = People('egon', 1.8, 70)
    # print(p.bmi())
    # p.height=1.90
    # print(p.bmi)
    
    
    # 2、
    # class People:
    #     def __init__(self,name):
    #         self.__name=name
    #
    #     @property
    #     def name(self):  # get
    #         return "名字:%s" %self.__name
    #
    #     @name.setter
    #     def name(self,val):  # set
    #         if type(val) is not str:
    #             print("名字必须是str类型")
    #             return
    #         self.__name = val
    #
    #     @name.deleter
    #     def name(self):  # del
    #         print('不让删除')
    #
    # p=People('egon')
    
    # print(p.name)
    # p.name=123
    # del p.name
    # print(p.name)
    
    # 3、
    class People:
        def __init__(self,name):
            self.__name=name
    
        def get_name(self):  # get
            return "名字:%s" %self.__name
    
        def set_name(self,val):  # set
            if type(val) is not str:
                print("名字必须是str类型")
                return
            self.__name = val
    
        def del_name(self):  # del
            print('不让删除')
    
        name = property(get_name,set_name,del_name)
    
    p=People('egon')
    property装饰器

    08三大特性之继承

    """
    1 什么是继承?
        继承是一种新建子类的方式,新建的类称之为子类,被继承的类称之为父类、基类、超类
        继承的特点:子类会遗传父类的所有属性
    
    2 为何要继承
        类存在的意义是为了解决对象与对象之间的冗余问题
        而继承的意义是为了解决类与类之间冗余问题
    
        继承体现的一种耦合思想,于扩展性的增强无益
    
    3 如何继承
        语法:python支持单继承与多继承
    
        单继承: 一个子类只能继承一个父类
        多继承: 一个子类可以同时继承多个父类
    
        ps:继承表达的是一个is-a的关系
            单继承符合is-a的关系,可以让继承结构相对简单一点
    
            而多继承不符合is-a的关系,盲目使用多继承会加大继承结构的复杂度,所以继承的正确打开方式是Mixins机制
    
    """
    
    
    # class Parent1:
    #     pass
    #
    # class Parent2:
    #     pass
    #
    # class Sub1(Parent1):
    #     pass
    #
    # class Sub2(Parent1,Parent2):
    #     pass
    #
    #
    # print(Sub1.__bases__)
    # print(Sub2.__bases__)
    #
    #
    
    # 案例1
    # class Student:
    #     school = "oldboy"
    #
    #     def __init__(self, name, age, gender,stu_id):
    #         self.name = name
    #         self.age = age
    #         self.gender = gender
    #
    #         self.stu_id = stu_id
    #
    #     def choose(self):
    #         print('is choosing course')
    #
    #
    # class Teacher:
    #     school = "oldboy"
    #
    #     def __init__(self, name, age, gender,level,salary):
    #         self.name = name
    #         self.age = age
    #         self.gender = gender
    #
    #         self.level = level
    #         self.salary = salary
    #
    #     def set_score(self, stu_obj, num):
    #         stu_obj.score = num
    #         print("老师<%s>给学生<%s>打了 %s 分" %(self.name,stu_obj.name,num))
    #
    # stu_obj1=Student("tom",18,'male',3536)
    # tea_obj1=Teacher("egon",18,'male',10,3000)
    #
    # # tea_obj1.set_score(stu_obj1,60)
    # # print(stu_obj1.score)
    
    # 如何在子类派生的新方法中重父类的功能
    # 方案一:指名道姓地调用某一个类的函数,不依赖于继承
    class People:
        school = "oldboy"
        #            空对象,"tom",18,'male'
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    class Student(People):
        #            空对象,"tom",18,'male',3536
        def __init__(self,name,age,gender,stu_id):
            People.__init__(self,name,age,gender)
    
            self.stu_id=stu_id
    
        def choose(self):
            print('is choosing course')
    
    class Teacher(People):
        def __init__(self, name, age, gender,level,salary):
            People.__init__(self,name,age,gender)
    
            self.level = level
            self.salary = salary
    
        def set_score(self, stu_obj, num):
            stu_obj.score = num
            print("老师<%s>给学生<%s>打了 %s 分" %(self.name,stu_obj.name,num))
    
    stu_obj1=Student("tom",18,'male',3536)
    tea_obj1=Teacher("egon",18,'male',10,3000)
    
    print(stu_obj1.__dict__)
    print(tea_obj1.__dict__)
    三大特性之继承

    09属性的查找

    # 在单继承背景下的属性查找:
    # 1、obj.x
    # 对象=》对象的类=》父类=》父父类。。。
    
    # 2、类名.x
    # 当前类=》父类=》父父类。。。
    
    # 示例1:
    # class Foo:
    #     def f1(self):
    #         print("Foo.f1")
    #
    #     def f2(self):
    #         print('Foo.f2')
    #         self.f1()  # obj.f1()
    #
    # class Sub(Foo):
    #     def f1(self):
    #         print("Sub.f1")
    #
    # obj=Sub()
    # obj.f2()
    # """
    # Foo.f2
    # Sub.f1
    # """
    
    # 示例2
    class Foo:
        def __f1(self):  # _Foo__f1
            print("Foo.f1")
    
        def f2(self):
            print('Foo.f2')
            self.__f1()  # self._Foo__f1
    
    class Sub(Foo):
        def __f1(self):  # _Sub__f1
            print("Sub.f1")
    
    obj=Sub()
    obj.f2()
    """
    Foo.f2
    Sub.f1
    """
    属性的查找

    10多继承

    #coding:utf-8
    # 在python中,针对每一个类python解释器都会基于c3算法为其计算出一个MRO列表
    # ps: 在python中有新式类与经典类之分
    # 新式类:但凡是继承了object类的子类,以及该子类的子子孙孙类都是新式类
    # 经典类:没有继承object类的子类,以及该子类的子子孙孙类都是经典类
    # 注意:在python3中,如果一个子类没有继承任何类,那么python会让其默认继承object类
    #       所以说,只有在python2中才存在经典类
    # class Foo(object):
    #     pass
    #
    # class Bar(Foo):
    #     pass
    #
    # class A(Bar):
    #     pass
    #
    # # print(A.mro())
    # # obj=A()
    # # obj.x
    #
    # print(Bar.mro())
    # b=Bar()
    # # b.x
    
    # !!! 重要结论:由谁引发的属性查找,就参照谁的MRO列表
    # class E:
    #     def test(self):
    #         print('from E')
    #
    #
    # class F:
    #     def test(self):
    #         print('from F')
    #
    #
    # class B(E):
    #     def test(self):
    #         print('from B')
    #
    #
    # class C(F):
    #     def test(self):
    #         print('from C')
    #
    #
    # class D:
    #     def test(self):
    #         print('from D')
    #
    #
    # class A(B, C, D):
    #     # def test(self):
    #     #     print('from A')
    #     pass
    
    
    # print(A.mro())
    '''
    [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class 'object'>]
    '''
    
    # obj = A()
    # obj.test()
    
    # 菱形继承:一个子类继承的多个父类汇聚到一个非object类
    # 新式类与经典类关于属性的查找不一样
    # (1)新式类:广度优先
    # (2)经典类:深度优先
    
    class G: # 在python2中,未继承object的类及其子类,都是经典类
        # def test(self):
        #     print('from G')
        pass
    
    class E(G):
        # def test(self):
        #     print('from E')
        pass
    
    class F(G):
        def test(self):
            print('from F')
    
    class B(E):
        # def test(self):
        #     print('from B')
        pass
    
    class C(F):
        def test(self):
            print('from C')
    
    class D(G):
        def test(self):
            print('from D')
    
    # print(D.mro())
    class A(B,C,D):
        # def test(self):
        #     print('from A')
        pass
    
    obj = A()
    # print(A.mro())
    obj.test()
    多继承

    11supper方法

    # 如何在子类派生的新方法中重父类的功能
    # 方案一:指名道姓地调用某一个类的函数,不依赖于继承
    # 方案二:super()会返回一个特殊的对象,super().x该对象会参照当前类的mro列表去父类里找,严格依赖继承
    class People:
        school = "oldboy"
        #            空对象,"tom",18,'male'
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def tell_info(self):
            print("名字:%s" %self.name)
            print("年龄:%s" %self.age)
            print("性别:%s" %self.gender)
    
    class Student(People):
        #            空对象,"tom",18,'male',3536
        def __init__(self,name,age,gender,stu_id):
            # People.__init__(self,name,age,gender)
            # super(Student,self).__init__(name,age,gender)  # 在python2中
            super().__init__(name,age,gender)  # 在python2中
    
            self.stu_id=stu_id
    
        def choose(self):
            print('is choosing course')
    
        def tell_info(self):
            print("学号:%s" %self.stu_id)
            super().tell_info()
    
    class Teacher(People):
        def __init__(self, name, age, gender,level,salary):
            # People.__init__(self,name,age,gender)
            super().__init__(name,age,gender)  # 在python2中
    
            self.level = level
            self.salary = salary
    
        def set_score(self, stu_obj, num):
            stu_obj.score = num
            print("老师<%s>给学生<%s>打了 %s 分" %(self.name,stu_obj.name,num))
    
    stu_obj1=Student("tom",18,'male',3536)
    tea_obj1=Teacher("egon",18,'male',10,3000)
    
    # print(stu_obj1.__dict__)
    # print(tea_obj1.__dict__)
    
    # stu_obj1.tell_info()
    # tea_obj1.tell_info()
    
    
    class A:
        def test(self):
            super().test() # 参照属性发起者的mro,去父类里找属性
    
    class B:
        def test(self):
            print('from B')
    
    class C(A,B):
        pass
    
    # obj=C()
    # obj.test()
    # print(C.mro())
    
    obj=A()
    print(A.mro())
    obj.test()
    supper方法
  • 相关阅读:
    Android应用性能测试之CPU和内存占用
    每天一个linux命令(30): chown命令
    安装apk时出现错误Failure [INSTALL_FAILED_DEXOPT]问题解决的方法
    android adb shell 命令大全
    adb logcat命令查看并过滤android输出log
    Ubuntu里字符编码设置
    linux下GBK->UTF-8文件编码批量转换脚本
    Android开发之如何保证Service不被杀掉(broadcast+system/app)
    android的m、mm、mmm编译命令的使用
    解决 samba不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接
  • 原文地址:https://www.cnblogs.com/2722127842qq-123/p/13586597.html
Copyright © 2020-2023  润新知