zoukankan      html  css  js  c++  java
  • python笔记(19)--面向对象三大特性补充

    内容目录:

    • 继承
    • 多态
    • 封装

    内容回顾

    • 面向对象编程:

      • 思想:角色的抽象,创建类,创建角色(实例化),操作这些实例

      • 面向对象的关键字

      • #示例:
        class Object:		#类名首字母大写
            name = 'lyn'
            def __init__(self):pass
        
        Object.name		#存储在类的命名空间里
        obj = Object()		#实例化:创造一个self对象,执行init方法,返回self对象给obj
        
        #对象.属性
        #对象.方法   相等于    类名.方法(对象)
        #对象可以使用静态变量吗?	True
        #类可以使用对象的属性吗?	False
        
      • 组合(最起码是两个类)

        • 一个类的对象是另外一个类对象的属性

        • class A:
              def __init__(self):
                  self.name = 'alec'
           
          class B:
              def __init__(self,year,month,day):
                  self.year = year
                  self.month = month
                  self.day = day
                  
          b = B(19, 1, 17)
          print(b.year,b.month,b.day)
          a = A()
          a.birth = b
          print(a.birth.year)
          

    内容详细:

    1.继承

    1.1 单继承

    • 类和类之间才能被称为继承,类和对象之间只能是实例化

    • 一个类可以被多个类继承 ----只在python里适用

      class A:pass        #父类,基类,超类
      class B:pass        #父类,基类,超类
      
      class A_son(A):pass #子类,派生类
      class AB_son(A,B):pass  #可以继承多个父类
      
      #查看继承的父类
      print(A_son.__bases__)      #(<class '__main__.A'>,)
      print(AB_son.__bases__)     #(<class '__main__.A'>, <class '__main__.B'>)
      
    • 新式类:python3里所有的类都有父类,如果没有标识继承的父类,那它就是 object 的子类

    • 继承示例:

      # 把Dog和Person类中的同样的变量提取至Animal类中
      class Animal:
          def __init__(self,name,aggr,hp):
              self.name = name
              self.aggr = aggr
              self.hp = hp
      
      # 继承Animal类,可以使用父类中的变量
      class Dog(Animal):
          def bite(self,person):
              person.hp -= self.aggr
      
      class Person(Animal):
          pass
      
      #正常传值和调用
      jin = Dog('史努比',200,500)
      print(jin.name)
      
    • 面试题:

      class Animal:
          def __init__(self):
              print('执行Animal.__init__')
              self.func()
          def eat(self):
              print('%s eating'%(self.name,))
          def drink(self):
              print('%s drink' % (self.name,))
          def func(self):
              print('Animal.func')
      
      class Dog(Animal):
          def guard(self):
              print('guard')
          def func(self):
              print('Dog.func')
      
      dog = Dog()
      #结果为:
      # 执行Animal.__init__
      # Dog.func
      

    1.2 派生属性

    • 派生属性:继承父类中的变量,然后自己也创建了一些特有属性

      class Animal:
          def __init__(self,name,blood,aggr):
              self.name = name
              self.blood = blood
              self.aggr = aggr
      
      class Dog(Animal):
          def __init__(self,name,blood,aggr,kind):
              Animal.__init__(self,name,blood,aggr)	#调用了父类的属性
              self.kind = kind        #自己创建的,属派生属性
      
    • 派生方法:父类中没有的方法,在子类中出现,叫做派生方法

      • 只要是子类的对象调用,子类中有的方法一定用子类的,子类中没有才能去找父类的,都没有则报错
      • 如果既想实现新功能也想适用父类的功能,还需在子类中调用父类的方法
      class Animal:
          def __init__(self,name,blood,aggr):
              self.name = name
              self.blood = blood
              self.aggr = aggr
          def eat(self):
              print('生命值增加100点')
              self.blood += 100
      
      class Dog(Animal):
          def __init__(self,name,blood,aggr,kind):
              Animal.__init__(self,name,blood,aggr)
              self.kind = kind
          def eat(self):
              Animal.eat(self)    #自己有并还想用父类的,则调用父类方法
              self.aggr += 10
          def bite(self,person):
              person.blood -= self.aggr
              print('狗咬人,人剩了%s血'%(person.blood))
      
      jin = Dog('金老板',100,20,'teddy')
      jin.eat()
      print(jin.blood,jin.aggr)
      

    总结:

    • 父类中没有的属性,在子类中出现,叫做派生属性
    • 父类中没有的方法,在子类中出现,叫做派生方法
    • 只要是子类的对象调用,子类中有的方法一定用子类的,子类中没有才能去找父类的,都没有则报错
    • 如果子类调用的方法自己有并还想用父类的,单独调用父类的,需要自己传self方法

    1.3 关键字super的用法:只能在新式类中使用

    • super的内部用法,相等于调用父类的init方法

    • super的外部用法,只调用父类的方法: super(子类名,实例化对象).父类中的方法

      class Animal:
          def __init__(self,name,blood,aggr):
              self.name = name
              self.blood = blood
              self.aggr = aggr
          def eat(self):
              print('生命值增加100点')
              self.blood += 100
      
      class Dog(Animal):
          def __init__(self,name,blood,aggr,kind):
              super().__init__(name,blood,aggr)      #内部使用super方法,相等于Animal.__init__(self,name,blood,aggr)
              self.kind = kind
          def eat(self):
              self.aggr += 10
          def bite(self,person):
              person.blood -= self.aggr
              print('狗咬人,人剩了%s血'%(person.blood))
      
      jin = Dog('金老板',100,20,'teddy')
      jin.eat()                   #只调用自己的方法
      super(Dog,jin).eat()        #super用法:只调用父类的方法
      print(jin.blood,jin.aggr)
      

    1.4 多继承

    • 多继承中,我们子类的对象调用一个方法,默认是就近原则

      class A:
          def func(self):print('A')
      class B:
          def func(self):print('B')
      class C(A,B):					#继承父类时,先找A,再找B,顺序查找
          # def func(self):print('C')
          pass
      
      c = C()
      c.func()						#结果为A
      
    • 查看继承关系: 对象.mor()

      #接上面列子
      print(C.mro())  
      #[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
      
    • 钻石继承

      • py2中经典类中遵循深度优先,py3中新式类遵循广度优先

    • 多继承

    2.多态

    • 接口类和抽象类 在python当中的应用点并不是非常必要的

      • 使用abc模块来规范子类,必须有父类中的方法
      import abc
      class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
          @abc.abstractmethod
          def talk(self):
              pass
      
      class People(Animal): #动物的形态之一:人
          def talk(self):
              print('say hello')
      
      class Dog(Animal): #动物的形态之二:狗
          def talk(self):
              print('say wangwang')
      
      class Pig(Animal): #动物的形态之三:猪
          def talk(self):
              print('say aoao')
      
    • 因为python中不崇尚用父类约束子类的方法,因为python当中有鸭子类型

    3.封装

    3.1 类中私有

    • 所有的私有,都是在变量的左边加上双下划线

      • 对象的私有属性
      • 类中的私有方法
      • 类中的静态私有属性
    • 所有的私有的,都不能在类的外部使用

      class Person:
          __key = 123                     # 私有静态属性
          def __init__(self,name,passwd):
              self.name = name
              self.__passwd = passwd      # 私有属性
      
          def __get_pwd(self):            # 私有方法
              # print(self.__dict__)
              return self.__passwd
      
          def login(self):
              return self.__get_pwd()
      
      alec = Person('alec','123456')
      print(alec.__dict__)                # 查看类内部的所有属性,然后可以强制调用私有属性
      pwd =alec.login()
      print(pwd)
      
    • 应用场景:

      • 隐藏起一个属性,不想让类的外部调用
      • 保护这个属性,不想让属性随意被改变
      • 保护这个属性不被子类继承
  • 相关阅读:
    No-3.Linux 终端命令格式
    No-2.常用 Linux 命令的基本使用
    No-1.文件和目录
    No-7.运算符
    No-6.If语句
    No-5.变量的命名
    YOLOv4详细分析 | 细数当前最佳检测框架小细节(附论文及源码下载)
    案例】S7-200SMART 实时时钟如何在MCGS触摸屏上显示并写入
    卡尔曼滤波:从入门到精通
    mmdetection最小复刻版(七):anchor-base和anchor-free差异分析
  • 原文地址:https://www.cnblogs.com/lynlearnde/p/12912283.html
Copyright © 2011-2022 走看看