Loading

12-封装和继承

限制属性的名称

  • 限制属性只能有name, age
    • __slots__ = ('name', 'age')

私有属性

  • 面向对象特点:1.封装 2.继承 3.多态 4.抽象
  • 类可以封装属性和方法
    • 公有变量:在类的外部可以访问(对象.属性)
  • 私有属性与方法
    • 对象属性又叫成员变量
    • 私有属性/变量只能在类内部使用
      • self.__age = age
    • 私有方法只能在类内部使用
      • def __get_age2(self):
    • 可以通过在类中建一个方法间接访问私有属性
    • 对象.类__属性,直接访问私有属性
      • print(a._A__age) # 但是不建议这样写

装饰器

  • @property
    • 作用:让函数可以当成属性来使用,相当于get方法
    • @property必须有返回值
    • print(cat.name)
      • 如果没有使用装饰器,调用函数:print(cat.name())
  • @x.setter
    • 作用:让函数当成属性来使用,相当于set方法
    • 必须有一个参数
      • @color.setter
      • def color(self, newColor):
        • self.__color = newColor
      • 调用
      • cat.name = '狸猫'

注意遍历元素为对象的列表时使用匿名函数

单继承

  • # 父类:Ipod
    class Ipod(object):
        def __init__(self, color):
            self.color = color
    
        def listen_music(self):
            print('听音乐')
    
    # 子类:Ipad
    class Ipad(Ipod):
        def __init__(self, color, type): # 继承自己写的父类,一定要调用一下init
            # 调用父类中的init方法:
            # Ipod.__init__(self, color)  # 显式调用
            super().__init__(color)  # 此写法也可以,隐式调用
            self.type = type  # 字类自己的属性
    
        def watch_movie(self):
            print('看电影')
    
    # 对象
    ipod = Ipod('黑色')
    print(ipod.color)
    ipod.listen_music()
    
    ipadmini = Ipad('土豪金', 'mini')
    print(ipadmini.color)
    print(ipadmini.type)
    ipadmini.listen_music()
    ipadmini.watch_movie()
    
    # Iphone(孙子类)
    # 属性:颜色,类型,价格
    # 方法:听音乐,看电影,打电话
    class Iphone(Ipad):
        def __init__(self, color, type, price):
            super().__init__(color, type)
            self.price = price
    
        def call_phone(self):
            print('打电话')
    
    # 对象
    iphone11 = Iphone('黑色', 'iphone11', '8888')
    print(iphone11.color, iphone11.type, iphone11.price)
    iphone11.listen_music()
    iphone11.watch_movie()
    iphone11.call_phone()
    
    • 父类,基类
    • 子类,派生类
    • object:超类,根类,不写,默认继承object
    • 继承自己写的父类,一定要调用父类的__init__
      • 显式调用
        • Ipod.__init__(self, color)
      • 隐式调用
        • super().__init__(color)
    • 多重继承时,只写继承自己的父类即可,不用再写继承“爷类”
    • 子类在继承父类的属性时,要把父类的所有属性都调出来,子类的属性是大于等于父类的属性的

多继承

  • # 多继承:一个子类同时继承多个父类
    class Father(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def work(self):
            print('会工作赚钱')
    
    # Mother
    
    class Mother(object):
        def __init__(self, height, face_value):
            self.height = height
            self.face_vlaue = face_value
    
        def cook(self):
            print('会做饭')
    
    # Son
    # super() 在单继承中,可以理解为父类, 在多继承中表示__mro__列表的上一级
    class Son(Father, Mother):  # 有顺序
        def __init__(self, name, age, height, face_value, girl_friend):
            # 显式调用
            # Father.__init__(self, name, age)
            # Mother.__init__(self, height, face_value)
    
            # 隐式调用
            # super().__init__(name, age)
            super(Son, self).__init__(name, age)  # Son上一级
            super(Father, self).__init__(height, face_value)  # Father上一级
            self.girlfriend = girl_friend
    
        def play(self):
            print('玩游戏')
    
    # 对象
    nezha = Son('哪吒', 10, 120, 100, '女朋友')
    print(nezha.name, nezha.age, nezha.height, nezha.face_vlaue, nezha.girlfriend)
    nezha.work()
    nezha.cook()
    nezha.play()
    
    • 多继承:一个子类同时继承多个父类

    • 显式调用

      • 注意定义子类继承父类时的顺序
        • Father.__init__(self, name, age)
        • Mother.__init__(self, height, face_value)
    • 隐式调用(链式调用)

      • super(Son, self).__init__(name, age)
      • super(Father, self).__init__(height, face_value)
    • mro算法

      • print(Son.__mro__) # mro算法,根据结果按顺序从左往右依次继承

        • (<class '__main__.Son'>, <class '__main__.Father'>, <class '__main__.Mother'>, <class 'object'>)
          

私有属性和私有方法不能被继承

  • 类内部的方法可以调用私有属性
  • 子类不可以使用父类的私有属性
  • 子类中可以使用父类的成员方法和成员变量(对象属性)
  • 子类中不可以调用父类的私有方法

override重写

  • 在子类中出现和父类同名的函数,则认为该函数是对父类中函数的重写

  • 自定义函数重写

    • 函数重写的时机:在继承关系中,如果父类中函数的功能满足不了子类的需求,则在子类中需要重写
  • 系统函数重写

    • # __str__
      # 1.必须返回字符串
      # 2.作用是让打印对象(用self调用)的结果变成当前函数(__str__)的返回值
      def __str__(self):
      	return f'姓名:{self.name},颜色:{self.color}'
      
      def __repr__(self):
      	return f'姓名2:{self.name},颜色2:{self.color}'
      
    • __str__(优先使用)

      • 适合给开发者看
    • __repr__

      • repr(dog)
        • 调用__repr__的指定方法,一定会调用__repr__
        • 给机器看
    • 1.当一个类继承自object的时候,打印对象获取的是对象的地址,等同于通过子类对象调用父类中__str__

    • 2.当打印对象的时候,默认调用了__str__函数

    • 3.重写__str__的作用:为了调试程序

posted @ 2020-11-20 00:07  lotuslaw  阅读(94)  评论(0编辑  收藏  举报