美文网首页
007-面向对象2

007-面向对象2

作者: 痞子_4ae7 | 来源:发表于2020-05-14 11:48 被阅读0次

    del方法

    • 调用:
    创建对象时,python解释器会默认调用__init__方法,当删除一个对象时,
        python解释器也会调用一个方法,这个方法是:  __del__()
    
    • 案例:
    class Animal:
        # 对象初始化时调用
        def __init__(self,name):
            self.name = name
            print(self.name+"来了")
        # 对象被回收时调用
        def __del__(self):
            print(self.name+"被妖怪抓走了")
    # 创建对象,初始化 init方法调用
    an = Animal("唐僧")
    # 手动删除对象,之后将不能在被使用,如果使用会报错
    # del an
    print(an.name)
    # 如果没有手动删除,对象将在使用完才被系统收走
    
    • 案例:

      # 创建对象,初始化 init方法调用
      an = Animal("唐僧")
      # 手动删除对象,之后将不能在被使用,如果使用会报错
      an1 = an
      an2 = an
      print(id(an))
      print(id(an1))
      print(id(an2))
      print("马上删除对象an")
      del an
      print("马上删除对象an1")
      del an1
      print("马上删除对象an2")
      # 这句代码执行完毕,对象才会被真正删除(引用计数)
      del  an2
      
      • 引用计数:
      刚创建出来的时候为2,增加一个引用,引用计数+1,
      del  对象  ,可以减少引用计数,当引用计
      数为1时,在del 对象,才会真正被回收
      

    单继承

    • 继承概念

      用来描述类与类之间的一种关系:
      父类、超类、基类
      子类、派生类
      
    • 继承的语法

      class  子类(父类名,...):
      方法...
      如果一个类没有明确指明父类,则它的父类为object
      
    • 案例:

      - 定义Cat类,包含属性:  name,color,age;方法:eat() sleep() catchmouse()
      - 定义Dog类,包含属性: nage,color,age;方法:eat() sleep() lookafterHouse()
      - 发现许多重复的东西,优化,抽离一个父类Animal出来
      
    • 总结:

      - 子类可以继承父类中所有的属性跟方法(私有除外)
      - 私有属性不能通过对象直接访问,但可以通过方法访问
      - 私有方法,不能通过对象直接访问
      
    • 属性自动化赋值(高级用法)(setattr,getattr,hasattr,isinstance函数的使用)

      # 属性自动化赋值
      class Dog():
          def __init__(self,name,age,gender,color,breed):
              print(locals())
              # pass
              self.attributeFromdict(locals())
          # 自定义方法,设置属性
          def attributeFromdict(self,d):
              self = d.pop('self')
              for n, v in d.items():
                  # 内置函数,为self的属性赋值value
                  setattr(self,n,v)
          def showinfo(self):
              print(self.name)
              print(self.age)
              print(self.breed)
              print(self.gender)
      dog =Dog('aa',12,'男','red','京巴')
      dog.showinfo()
      

    多继承

    • 概念

      所谓多继承,就是一个类同时有多个父类
      思考:狼狗的父类
      狼、狗
      
    • 语法

      class 子类(父类1,父类2):
      方法...
      如果父类1,父类2中都有属性,则以先继承的类为标准,如果两个父类存在同名方法,则一样
      以先继承的类为准,所有父类中的非同名方法都能被继承到
      
    • 案例

      class AAA():
          def methodAAA(self):
              print("a的方法a")
      class BBB():
          def methodBBB(self):
              print("b的方法b")
      class CCC(AAA,BBB):
          def methodCCC(self):
              self.methodAAA()
              self.methodBBB()
              print("c的方法c")
      ccc = CCC()
      ccc.methodCCC()
      # 执行结果
      # a的方法a
      # b的方法b
      # c的方法c
      

      两个父类中的方法,属性,都会被子类继承
      思考: 如果父类中有同名方法,会怎么样?

      class AAA():
          def methodAAA(self):
              print("a的方法a")
          # 新增方法,BBB类中有同名方法
          def methodBBB(self):
              print("a的方法b")
      class BBB():
          def methodBBB(self):
              print("b的方法b")
      class CCC(AAA,BBB):
          def methodCCC(self):
              self.methodAAA()
              self.methodBBB()
              print("c的方法c")
      ccc = CCC()
      ccc.methodCCC()
      # 执行结果
      # a的方法a
      # a的方法b
      # c的方法c
      

    重写父类的方法与调用父类的方法

    • 方法重写概念:

      所谓重写,就是在子类中,有一个和父类相同名字的方法,子类中的方法会覆盖掉父类中的同名方法
      
    • 方法重写案例:

      class SuperClass():
          def __init__(self):
              print("父类的初始化方法")
          def test(self):
              print("父类的测试方法")
      class SubClass(SuperClass):
          def __init__(self):
              print("子类的初始化方法")
          def test(self):
              print("子类的测试方法")
      sub = SubClass()
      # 这里的test方法,调用的为子类中重写的方法
      sub.test()
      # 执行结果
      # 子类的初始化方法
      # 子类的测试方法
      
    • 调用父类方法:

    class SuperClass():
        def __init__(self,name):
            self.name = name
        def test(self):
            print("父类的测试方法")
    class SubClass(SuperClass):
        def __init__(self,name,age):
           # SuperClass.__init__(self,name)
    # super(SubClass, self).__init__(name)
    super().__init__(name)
            self.age  = age
        # 子类重写父类方法
        def test(self):
            print("子类的测试方法")
            print('name:'+self.name+",age:"+str(self.age))
    
    sub = SubClass('aa',12)
    sub.test()
    # 执行结果
    # 子类的测试方法
    # name:aa,age:12
    

    多态

    • 概念

      • 定义时的类型跟运行时的类型不一样,此时就成为多态
        严格意义上来讲,python中的多态不叫真正的多态,称之为鸭子类型更合适
      • 鸭子类型
      “鸭子类型”的语言是这么推断的:一只鸟走起来像鸭子、游起泳来像鸭子、叫起来也像鸭子,
      那它就可以被当做鸭子。也就是说,它不关注对象的类型,而是关注对象具有的行为(方法)。
      
      • 鸭子类型弊端
      “鸭子类型”语言的程序可能会在运行时因为不具备某种特定的方法而抛出异常:
      
      案例1:
      如果一只小狗(对象)想加入合唱团(以对象会不会嘎嘎嘎叫的方法为检验标准),
      也学鸭子那么嘎嘎嘎叫,好吧,它加入了,可是加入之后,却不会像鸭子那样走路,
      那么,迟早要出问题的。
      
      案例2:
      一只小老鼠被猫盯上了,情急之下,它学了狗叫,猫撤了之后,小老鼠的妈妈不无感叹的
      对它说:看吧,我让你学的这门儿外语多么重要啊。这虽然是个段子,但是,由于猫在
      思考时,使用了 "鸭子测试",它以为会叫的就是狗,会对自己产生威胁,所以撤退了,
      也正是因为这个错误的判断,它误失了一次进食机会。
      
    • 用法

    class F1(object):
        def show(self):
            print("F1.show")
    class S1(F1):
        def show(self):
            print("S1.show")
    class S2(S1):
        def show(self):
            print("S2.show")
    def func(obj):
        obj.show()
    
    obj1 = F1()
    func(obj1)
    obj1 = S1()
    func(obj1)
    obj1 = S2()
    func(obj1)
    

    类属性、实例属性

    • 类属性
    属于类对象所拥有的属性,它被所有类对象的实例对象所公有,在内存中只有一份
    
    • 类属性的访问方式

      • 在类外可以通过类名访问
      类名.属性名
      
      • 在类外可以通过实例对象访问
      对象名.属性名
      
    • 案例:

    class Student:
        # 类属性
        schoolName="西三旗校区"
        def __init__(self,name,age):
            # 实例属性
            self.name = name
            self.age = age
    st1 = Student('陈独秀',29)
    # 通过类名访问类属性
    print(Student.schoolName)
    # 通过对象访问类属性
    print(st1.schoolName)
    # 通过对象访问修改属性,会新增对象属性,之后通过对象访问类属性将无法访问到,因为会被新增的对象属性屏蔽
    st1.schoolName = '京南校区'
    # 类属性访问结果不变
    print(Student.schoolName)
    # 这只能访问到对象属性
    print(st1.schoolName)
    # 可以手动删除新增的对象属性
    del st1.schoolName
    # 因为对象属性被删除,所以,这访问的依旧是类属性
    print(st1.schoolName)
    

    静态方法和类方法

    • 类方法

      • 概念
      是类对象所拥有的方法,需要用@classmethod来表示,类方法第一个参数必须为类对象
      一般使用'cls', 类方法能够通过类名和对象进行访问
      
      • 用法:
      class Student:
          # 类属性
          schoolName="西三旗校区"
          def __init__(self,name,age):
              # 实例属性
              self.name = name
              self.age = age
          #   类方法 (可以直接访问类属性)
          @classmethod
          def getSchoolName(cls):
              return cls.schoolName
      @classmethod
      def setSchoolName(cls,newSchoolName):
          cls.schoolName = newSchoolName
      st2 = Student('李大钊',30)
      Student.schoolName = '北平学校'
      # 通过对象访问类方法
      print(st2.getSchoolName())
      # 通过类名方法类方法(使用较多)
      print(Student.getSchoolName())
      Student.setSchoolName('同济学校')
      print(Student.getSchoolName())
       注意: 类方法中可以直接修改当前类的类属性
      
    • 静态方法

      • 概念
      需要使用@staticmethod进行修饰,静态方法不需要定义参数
      
      • 用法
      可以访问类属性,但是必须通过类名,
      调用方式:可以通过类名,对象进行调用
      class Student:
          # 类属性
          schoolName="西三旗校区"
          def __init__(self,name,age):
              # 实例属性
              self.name = name
              self.age = age
          #   静态方法 (可以通过类名访问类属性)
          @staticmethod
          def getSchoolName():
              return Student.schoolName
      

    简单总结对比:

    • 成员属性、类属性、私有属性
    • 成员方法、类方法、静态方法、私有方法

    相关文章

      网友评论

          本文标题:007-面向对象2

          本文链接:https://www.haomeiwen.com/subject/fyftohtx.html