zoukankan      html  css  js  c++  java
  • python第四周总结:面向对象总结:面向对象,类,对象,初始化函数init, 绑定和非绑定方法 继承,属性存放位置和查找顺序,抽象,派生和覆盖,一切皆对象,子类访问父类的内容,继承的另一种使用方法,super()问题和mro列表,组合,菱形继承问题,接口和抽象类,鸭子类型

    本周总结

    面向对象------详细23.24.25.

    面向对象本周总结

    本周知识点
    1.面向对象与面向过程对比
    2.面向对象编程概念
    3.什么是对象
    4.类的使用
    5.对象的使用
     
    6.__init__函数 *****
    7.绑定方法和非绑定方法 *****
    8.1.抽象与继承
    8.2继承的另一种使用方式
    9.super()的问题  mro列表
    10.组合
    11.菱形的继承问题
    12.接口
    13.抽象类
    14.鸭子类型
    1.面向对象编程概念
    1.1.面向对象
    1.1.1.面向过程编程思想
    关注的点就是完成任务的过程
    第一步
    第二步
    一步一步按照固定顺序来完成任务
    是一种机械化的思维,就像一条流水线,指定流水线只能生产指定产品
    缺点:
    牵一发而动全身 扩展性非常低,可维护性差
    优点:
    将复杂的事情,简单化,并流程化
    应用场景:
    对扩展要求较低的程序
    系统内核,shell脚本,计算器啥的

    2.1.2面向对象编程
    是一种编程思想
    面向:朝着 向着
    对象是什么
    面向对象关注点是对象,把你的思维角度从具体操作这 变成了一个指挥者
    例如把大象装进冰箱
    1.打开冰箱
    2.塞入大象
    3.关闭冰箱
    以上就是典型面向过程思想
    换成面向对象
    找一个具备装大象这个技能的对象 然后命令它装大象
    注意:对象不是凭空产生的 需要我们自己先设计对象 然后在使用它们
    2.1.3.面向对象优点:
    不需要在关注具体的实现细节 可以更好的关注业务逻辑
    扩展性提高了,维护性高,复用性高
    缺点:
    对比面向过程而言.程序需要先设计,结构更复杂,编程复杂度提高了
    无法准确预知执行结果
    应用场景:
    对于扩展性要求较高的应用程序
    qq,微信,王者荣耀

    面向对象是一种编程思想,让你不需要关心具体实现细节,而是关注对象
    优点:扩展性高,复用性,维护性

    2.2什么是对象?
    万事万物都是对象
    2.2.1对象:具备某种特征与行为的集合体并且是具体存在的就称之为对象
    如来佛祖,owen
    类: 某些具备相同特征和相同行为的集合体 ,是一种抽象概念 类型==类
    人,动物,狗,老男孩的老师
    特征==属性
    行为==技能

    2.2.2对象和类的关系
    在生活中 先有对象 再有类
    在代码中 必须现有类 才能产生对象 (因为你需要提前告诉计算机这个对象是什么样的有什么技能)
    编程思想不是某一个具体语言或技术 ,
    面向对象的语言:
    python,Java,C++,C#
    面向过程:
    C,ruby

    2.3.1.类的使用.py
    """
    使用class关键字来定义一个类
    类名称为大驼峰命名法
    所有单词首字母大写
    小驼峰 第一个单词首字母小写
    """
    # class ClassName:
    # pass
    class Student:
    # 描述特征使用变量 (属性)
    school = "olbBoy"
    # 描述技能使用函数 (方法)
    def say_hi():
    print("hello i am tiger")
    # class中的代码仅在第一次加载时执行
    print("test...")
    pass
    #
    print(Student.say_hi)
    Student.say_hi()
    print(Student.school)
    # Student.say_hi()

    # 调用类来获得一个对象
    # stu1 = Student()
    # stu1.say_hi()

    2.3.2.对象的使用.py
    class Person:
    country = "china"
    def eat(self):
    print("正在吃面...")

    p1 = Person()
    # print(p1)
    # print(Person)
    # print(p1.country)
    # p1.eat()
    # 为对象增加了属性
    p1.name = "张三"
    print(p1.name)

    # 给p1对象单独添加了country
    p1.country = "USA"
    # 在访问时优先访问自己名称空间的内容 如果找不到 会自动找类中的属性
    print(p1.country)
    print(Person.country)
    # 每个对象都会存储自己所在类的地址 可以使用__class__来访问
    print(p1.__class__)
    print(type(p1))

     

    3.面向对象的基本概念
        是一种编程思想,
        优点:扩展性高,复用性强,可维护性好
        缺点:编程复杂度提高了,需要先设计,结果无法准确预知
        使用场景:对扩展性要求高的程序

        面向过程:
        优点:复杂问题简单化,流程化
        缺点:扩展性极低,牵一发动全身,维护性相比OOP低
       使用场景:对扩展性要求低的程序
        将程序员从一个具体的操作者转变为指挥者
    4.类与对象的关系
        对象是  具备某些特征和行为的结合体,是具体存在的某个事物
        类 某些具备相同特征和相同行为的集合体,是一种抽象概念
        创建类的语法
        class  大驼峰命名:
            属性用变量标识 (数据属性)
            名称=值
            行为用函数表示 (函数属性/方法)
            def 函数名称
         创建对象
            类名加括号
            Person()
    5.属性的访问顺序
       优先访问对象自己的 如果没有 再访问类中的
     

     6.__init__函数
    6.1引申
    ## 类属性与对象属性
    类:
         类中应该仅存储所有对象共有的内容
    ​ 如:所有人的国籍相同那就放到类中
    对象:
         对象中存储每个对象独有的内容
    ​ 如:每个人的名字都不同
     
    6.2.## __init__方法的作用
            概念:
                   init 是初始化的缩写
           用途:
                 用于为对象的属性设置初始值
          特点:
    ```
    # 执行时机:当实例化产生对象时会自动执行该函数
    # 会自动传入需要初始化的对象
    # 初始化必须包含至少一个参数 用于表示对象本身
    # 该函数不允许有返回值 必须为None
    ```
     7.绑定方法和非绑定方法
    7.1## 绑定方法
    概念:
       绑定即两个东西绑在一起
       方法就是函数 
     
       那就是说绑定方法 == 绑定函数
     
    默认情况下: 在类中定义的方法 都是绑定方法
     
    绑定方法 :是把函数和对象绑定到一起
     
    7.2为什么要绑定:
     
         每个应用程序其实本质上都是在处理数据,那就必须明确 要处理的数据在哪里,如何处理
    绑定方法的好处在于,将需要处理的数据 以及处理数据的方法绑定在一起,这样一来 当你获得一个对象就同时获得 数据以及 相应的处理方法 ,简单的调用即可
     
    7.3### 绑定方法与普通函数的区别:
     
              当使用类调用时,就是一个普通函数 有几个参数就得传几个参数
              当用对象来调用时,是一个绑定方法了,会自动将对象作为第一个参数传入
     
    7.4一个类中可以有属性和方法
         方法分为两种
          1.绑定方法
    ​            1.1对象绑定方法
    ​               在使用对象调用时会自动传入对象本身
    ​            1.2类绑定方法
    ​            @classmethod
    ​            在使用对象调用时会自动传入类本身
    ​            在使用类来调用时也会自动传入类本身
    ​            单例模式中就会经常使用@classmethod
     
                1.3到底绑定给谁?
                    当你的方法执行过程中需要使用到对象中数据时就绑定给对象
                    当你的方法执行过程中需要使用到类中数据时就绑定给类
     
           2.非绑定方法
                即不需要对象中的数据 也不需要类中的数据  那就定义为非绑定方法,就是普通函数
               @staticmethod
     
     
     
     
    8.抽象与继承
     
    8.1# 继承:
             生活中:
                    继承指的是一种关系,在生活中通过继承关系,例如王思聪继承王健林,对于王思聪可以,可以直接使用王健林已经拥有的
                    被继承的一方(王健林) 称之为父   继承的一方(王思聪) 称之为子
             编程中:
                   在OOP(面向对象)中 继承描述是类和类之间的关系  例如b类继承a类  b类可以直接使用a类中的属性和方法
                  a是父类(基类,超类)  b是子类(派生类)
             优点:
                    好处:极大的提高了代码的复用性
     
    8.2如何使用继承,=>至少需要两个类
    语法:
    class 子类名称(父类名称):
    ​ pass
    ```
    class Teacher:
        school = "oldboy"
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def say_hi(self):
            print("hello i am %s" % self.name)
           
        def teach(self):
            print("正在教书......")
    class Student(Teacher):
        pass
    print(Student.school)
    print(Student.say_hi)
    print(Teacher.say_hi)
    s = Student("rose","123")
    s.say_hi()
    s.teach()
     
    在上述案例中通过继承 学生就拥有了老师的所有内容 
    但是学生不应该教书这个技能
    意味着这个继承关系 有问题 不合理
    需要先抽象 在继承
    ```
     
    8.3.# 抽像与继承
     
    继承之后可以直接使用父类的属性和方法
    使用继承时 应该先抽象 在继承
     
               抽象指的是 将一系列类中相同的特征和相同行为抽取 形成一个新的类
              会产生一些与原本业务不想关的类
              站在不同角度会得到不同的抽象结果
     
      案例:
    ```
    # 抽象得到的公共父类
    class OldBoyPerson:
        school = "oldboy"
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def say_hi(self):
            print("hello i am %s" % self.name)
    class Teacher(OldBoyPerson):
        def teach(self):
            print("正在教书......")
    class Student(OldBoyPerson):
        pass
    # 测试
    t = Teacher("owen",38)
    t.say_hi()
    t.teach()
    s = Student("歌王",20)
    s.say_hi()
    ```
     
    8.4# 在python3中任何类都直接或间接继承自Object  
    Object是所有类的基类 (根类)
    其中提供一系列方法, 这样一来 无论你是什么类 ,你都可以直接是object中已经存在的方法
    一切皆对象
    一切皆对象指的是  在python中您所使用到的任何数据都是对象  int  float list dict 模块 包 函数
     
    8.5# 属性的查找顺序
    #对象自己 - > 所在的类 -> 所在类的父类 -> 父类的父类  -> object
    class A:
        name = "scot"
        # def __str__(self):
        #     print("111111111")
        #     pass
        pass
    class B(A):
        name = "rose"
        pass
    b = B()
    # b.name = "jack"
    print(b.name)
    ```
    8.6# 派生与覆盖
    子类拥有与父类不同的内容 就称之为派生类
    覆盖 指的是子类出现了与父类完全相同(属性/方法)名称  根据查找顺序  就会优先找子类的 即覆盖了父类的内容
     
    # 在子类中访问父类已有的方法或属性
     
    class Person:
        text = "321"
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
        def sleep(self):
            print("人类 午睡 躺着睡!")
        def say_hi(self):
            print("my name :%s my age :%s my gender: %s " % (self.name,self.age,self.gender),end="")
       
    class Student(Person):
        text = "123"
        def __init__(self,name,age,gender,number):
     
    8.7直接调用父类的方法(三种:主要是super()应用)
            #======================================================================重点在这里
            # 由于父类已经存在一个方法可以完成这个三参数的初始化
            # 所以可以直接调用父类的初始化完成这部分的初始化工作
            # 方法1
            # Person.__init__(self,name,age,gender) # 指名道姓的调用
            # 方法2  在py2中不支持
            super().__init__(name,age,gender)
            # py2的写法
            # super(Student, self).__init__(name,age,gender)
            self.number = number
            #======================================================================
        # 访问父类的属性
        def show_text(self):
            print(self.text)
            print(super().text)
        def say_hi(self):
            super().say_hi()
            print("my number: %s" %  self.number)
            # print("my name :%s my age :%s my gender: %s my number: %s" % (self.name, self.age, self.gender,self.number))
    s = Student("jack",20,"man","007")
    s.say_hi()
    # s.show_text()
    ```
     
     
     
     
    8.8.继承的另一种使用方式   `*****`
       8.8.1通常:
                     最常见的是直接继承一个已经存在的类
       8.8.2另一种使用方式:
                     当你想要创建一个新的类 发现这个类中的一些 在某一个类中已经存在
                      那就没有必要从头开始写 ,可以直接继承已有的类 然后做补充
     案列:说明
    class MyList(list):
        def __init__(self,element_cls):
            # 当你覆盖了init方法时
            # 不要忘记调用super().init函数让父类完成原有的初始化操作
            super().__init__()
            self.element_cls = element_cls
           
        def append(self, object):
              #判定类型的两种方法:
            # if isinstance(object,str)#方法一
            if object.__class__ == self.element_cls:#方法二
                super().append(object)
            else:
                print("只能存储%s类型!" % self.element_cls.__name__)
    p=MyList(int)
    p.append(1)
    print(p)
    #值[1]
    ```
     
    9.super()的问题  mro列表 
     
        9.1python支持多继承  一个类可以同时继承多个父类
        9.2好处是更加灵活
        9.3问题是:属性的查找顺序该怎么确定
               # 问题:多继承时如果多个父类中出现了同名的属性/函数
               # 你不能用眼睛去判断查找顺序 ,需要使用mro列表来查看真正的继承顺序
               # 总结:super在访问父类属性时 是按照mro列表一层层往上找的
    #测试
    class A:
        def test(self):
            print("from A")
            super().test() # 应该报错..... 但是却执行成功了
    class B:
        def test(self):
            print("from B")
        pass
    class C(A,B):
        pass
    c = C()
    c.test()
    9.4#值--->super()的问题  :python支持多继承  一个类可以同时继承多个父类
    from A
    from B
    9.5#mro列表
    print(C.mro())
    #值表示调用顺序[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    #最后:尽量不要使用多继承
    ```
    10.#组合:
    组合:      指的是 一个类把另一个类的对象作为自己的属性 就称之为组合
    无处不在
     
                 当你定义一个类 并且这个类拥有某种类型的属性时 就称之为组合
    用途:
                  都是用用来重用代码的方式:
    组合与继承对比:
             组合描述的是 : 什么拥有什么的关系   学生 有 书  学生有手机
             继承描述的是 : 什么是什么的关系      麦兜是猪    猪猪侠也是猪
    """
    # class Person:
    #     def __init__(self,name):
    #         self.name = name
    #
    #
    # p = Person("rose")
    # print(p.name)
    class PC:
        def open_app(self,app_name):
            print("open %s" % app_name)
    class OldBoyStudent:
        def __init__(self,PC,notebook):
            self.PC = PC
            self.notebook = notebook
        pass
    pc = PC()
    notebook = PC()
    stu = OldBoyStudent(pc,notebook)
    ```
    11.菱形继承问题  ***
      菱形继承:------如果无菱形,深度优先
     11.1 概念:一个类有多个父类,并且多个父类之间又同时继承另一个父类,就产生了,菱形继承
     
     11.2新式类与经典类
    经典类:旧版,没有继承自object的类,统称为经典类 ,只出现在便宜中
    新式类:直接或间接继承了object的类就是新式类,py3全都是新式类
    11.2.1# 在py2中 A就是一个经典类——>没有mro列表
    # class A:
    #     pass
    print(A.__class__)
    print(type(A))
    值:
    <class 'type'>
    <class 'type'>
    Process finished with exit code 0
    11.2.2# 如果你的代码需要兼容py2 那应该显式的继承object  无论是直接还是间接继承
    案例:
    class B(object):
        pass
    class A(B):
        pass
    ```
     
    class A:
        # a = 1
        pass
    class B(A):
        # a = 2
        pass
    class C(A):
        # a = 3
        pass
    class D(A):
        # a = 4
        pass
    class E(B,C,D):
        # a = 5
        pass
    e1 = E()
    # print(e1.a)
    # 新式类的顺序
    # E  B C D A object
    # 经典类的顺序
    # E B A C D
    # print(E.mro())
    注意:经典类没有mro列表
    ```
     11.3属性查找顺序:
    如果出现菱形继承,
             经典类:在经典类中是深度优先
             新式类:由C3算法来确定继承顺序,先深度再广度,C3算法适用于属性查找顺序,通过mro()列表可以查到(print(E.mro()))
     
    12# .接口 ***
    12.1# 接口是什么 ?--一套协议规范
     
    例如USB  
    电脑内部具备USB相应的功能 如果要使用的话   就必须给外界提供一个使用方式,该方式就称之为接口 ,
     
    在程序中功能通常是用函数来表示, 对于外界而言 无需清楚函数时如何实现的 只要知道函数名即可, 这个函数名称就可以称之为接口 
    外界调用接口就能完成某个任务
     
    接口其实就是一组功能的定义,但是只清楚函数名称,而没有具体的实现细节
    相当于是一套规范,
     
    例如USB
           规定了接口的外观,大小,以及每条线路的功能是什么
           硬件开发商照着这个USB协议来生产设备,就可以被电脑使用
     
    具体表现形式:有一堆函数,但是只明确了函数的名称,没有明确函数具体怎么实现。
    ```
    class USB:
        def open(self):
            pass
        def close(self):
            pass
        def work(self):
            pass
    ```
    12.2好处:
              使用接口可以提高程序的扩展性
              只要对象按照接口规定方法来实现,使用者就可以无差别使用所有对象
    12.3问题:无法限制子类,必须真正实现接口层的功能
     
    13.抽象:
    ​       指的是 不清楚 不具体 看不懂
    13.1 抽象方法:
    ​          指的是 没有函数体的方法   用@abc.abstractmethod 装饰器
    ​          如果类中具备抽象方法 那么这个类就称之为抽象类
    13.2 抽象类的特点:
    ​        不能直接实例化  必须有子类覆盖了所有抽象方法后才能实例化子类
    13.3 与接口的区别:
    ​        接口是指:只有方法声明而没有实现体 ,  接口中所有方法都是抽象的
    ```
    import abc
    class Test(metaclass=abc.ABCMeta):#源类
        @abc.abstractmethod
        def say_hi(self):
            pass
    class TT(Test):
        def say_hi(self):
            print("i am TT obj")
    t = TT()
    t.say_hi()
    ```
     
    13.4问题:如果接口的子类没有实现接口中的方法,那是没有任何意义的
    13.5抽象类之所以出现的意义:
                                  通过抽象类来强行限制子类必须覆盖所有的抽象方法
     
    14.# 鸭子类型
    说如果一个对象叫声像鸭子,走路像鸭子,长得像鸭子,那它就是鸭子
    是python 推荐的方式,python不喜欢强行限制你
    ```
    案例1
    class PC():
        def conntent_device(self, usb_device):
            usb_device.open()
            usb_device.work()
            usb_device.close()
    class Mouse:
        # 实现接口规定的所有功能
        def open(self):
            print("mouse opened")
        def work(self):
            print("mouse working...")
        def close(self):
            print("mouse closed")
    mouse = Mouse()
    pc = PC()
    pc.conntent_device(mouse)
     
     
    class KeyBoard:
        def open(self):
            print("KeyBoard opened")
        def work(self):
            print("KeyBoard working...")
        def close(self):
            print("KeyBoard closed")
    key1 = KeyBoard()
    # 如果key1的特征和行为都像USB设备 那就把它当做USB设备来使用
    # 对于使用者而言可以不用关心这个对象是什么类,是如如何是实现,
    pc.conntent_device(key1)
    ```
     
    案例2:
    ```
    class Linux:
        def read_data(self,device):
            data = device.read()
            return data
        def write_data(self,device,data):
            device.write(data)
    class Disk:
        def read(self):
            print("disk reading....")
            return "这是一个磁盘上的数据"
        def write(self,data):
            print("disk writing %s..." % data)
    class UP:
        def read(self):
            print("disk reading....")
            return "这是一个U盘上的数据"
        def write(self,data):
            print("disk writing %s..." % data)
    l = Linux()
    d = Disk()
    data = l.read_data(d)
    l.write_data(d,"这是一个数据....")
    up1 = UP()
    l.read_data(up1)
    l.write_data(up1,"一个数据...")
    ```
    例如linux 有一句话叫一切皆文件
    之所以这么设计是为了提高扩展性,让Linux可以无差别对待任何设备!
     
     
     总结
     
    一。面向对象初识(认知)
    1.什么是面向对象?
    2.面向对象与面向过程的优缺点对比以及场景对比
    3.什么是对象?什么是类?
    4.类和对象的关系
    5.如何定义一个类
    6.如何创建对象
    7.属性的访问顺序
    8.类和名称空间是独立

    oop(面向对象)知识点:
     
    1.属性应该放在类中还是对象中 (公有的放在类中,各自独有的放在函数中)
     
     
    2.绑定方法  == 绑定函数
     
    对象绑定方法
    ​ 对象调用时 自动传入对象本身
    ​ 类调用时不会自动传参 有几个就需要传几个
     
    类绑定方法
    ​ @classmethod
    ​ 无论是对象还是类调用 都会自动传入类本身
     
    非绑定方法(静态方法)
    ​ @staticmethod
    ​ 谁调用都不会自动传参
    #面向对象的思路分析:
    # 在使用面向对象编程时      1.首先要想的是 =》需要什么对象,   2.这些对象具备什么样的属性和什么样的行为,   3.根据属性和行为创建对应的类
     

    二。面向对象的各类应用使用方式
    1.属性的的正确存放位置
        类中应该存储所有对象公共的内容
        对象中存储都是每个对象独有的(都不同)
    2.初始化函数
        给对象的属性赋初值 , 可以保证只要对象被创建就一定有相应的属性
        节省了重复代码
    3.绑定方法
        指的是 将类或对象与函数进行了绑定
        之所以绑定是为了提高整合度,后续在拿到对象就可以直接调用而无需关心 数据是什么 如何处理
        对象也可以看做是一个存储数据的容器
        3.1对象绑定方法
            默认情况下就是绑定给对象的
            当执行该方法时,需要访问对象中的内容
            当使用对象调用时 会自动传入对象本身作为第一个参数
            用类来调用时就是一个普通函数  该怎么传就这么传
        3.2类绑定方法
            当执行该方法时,需要访问类中的内容而不需要对象中的内容
            @classmethod
            无论使用类还是对象来调用都会自动传入类本身作为第一个参数
        4.非绑定方法
            既不需要访问类中的内容 也不需要访问对象中的内容  那就作为非绑定方法  就是一个普通函数  没有自动传值的效果
            @staticmethod
    5.继承
        说的是类与类之间的关系
        存在基础关系后 子类可以直接使用父类已经存在的内容   总的来说是为了提高代码的复用性
        例如猫 和狗 都属于动物类
        描述的是 什么是什么的关系  如:猫是动物
        要开始累积自己的类库 把经常使用的小功能写到一个模块中  以后可以直接调用
        class 子类(父类):
            pass
    6.属性查找顺序
        对象本身 -> 所在的类 -> 类的父类 -> .... object
    7.抽象
        使用基础时 应该先抽象 在继承
        抽象指的是 把一系列类中的相同的特征和行为抽取 形成一个新的类 (公共父类)
    8.派生与覆盖
    派生
        子类拥有与父类不同的内容
    覆盖
        子类出现了与父类完全相同的名字
    9.一切皆对象
        在py3里面所有东西全是对象  包括 int list 模块 函数 .....包等等....
        list.append(li,1)

    10.子类访问父类的内容
        1.指名道姓 直接写死了类名   即时不存在继承关系也能调用
        2.super().要访问的属性 (py3出现的)
        3.super(这个子类的名字,self).属性
    三。面向对象的各类实际应用解决
     
    1.继承的另一种使用方式
    2.super()的问题  mro列表
    3.组合
    4.菱形的继承问题
    5.接口
    6.抽象类
    7.鸭子类型
     
  • 相关阅读:
    JS基础
    NodeJs实现他人项目实例
    Node.js在任意目录下使用express命令‘不是内部或外部命令’解决方法
    HTTP基本知识
    RESTful API
    基本概念和方法1
    Node.js--安装express以及创建第一个express项目(windows)
    Node-debug方法
    css3动画划过有一个框
    translate 动画不同时间飞入文字
  • 原文地址:https://www.cnblogs.com/llx--20190411/p/10883441.html
Copyright © 2011-2022 走看看