面向对象 (一)

面向对象

  • 与面向过程相比:二狗子准备结婚,需要盖房子

    • 面向过程:数学逻辑的映射,学会做个好员工
    • 面向对象:生活逻辑的映射,学会做个好领导
  • 生活实例

    • 类: 人 手机 电脑
    • 对象: 习大大、小杰 小杰的 T2 手机、小明的 iPhone X 小杰的 Mac、小李的华硕
  • 官方定义:

    • 类:具有相同特征(属性和行为)事物的抽象
    • 对象:某个类的具象
  • 编程语言:

    • 类:是一种自定义的数据类型
    • 对象:某个类型的变量

类的语法

  • 定义类:

    1
    2
    class 类名
    内容
  • 示例:定义一个人的类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # 定义类
    class Person:
    # 行为的体现,通过方法

    # 吃饭
    def eat(self):
    print('红烧鸡腿我喜欢吃')

    # 打篮球
    def play(self):
    print('俺喜欢打篮球')


    # 声明对象
    bryant = Person()

    # 调用方法
    bryant.eat()
    bryant.play()

    # 设置属性:是动态添加的
    bryant.name = '科比·布莱恩特'
    # 获取属性
    print(bryant.name)
  • 语法:

    • 定义类需要使用关键字:class
    • 类名:原则上只要符合表示标识符的命名规范即可,但我们通常使用大驼峰 (每个单词首字母大写) 的风格
    • 不要忘记类名后边的冒号
    • 类的内容要进行缩进
    • 行为:通过函数体现,与外面定义函数的方式类似,第一个参数默认是 self
    • 属性:通过变量体现,属性是动态添加的,因此在定义时可以不体现
    • 成员访问:
      • 成员属性:对象.属性名
      • 成员方法:对象.方法名()
  • self

    • 示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      class Person:
      def run(self):
      # self表示当前对象:谁调用该方法就代表谁
      print('{}每天以2m/s的速度锻炼5km'.format(self.name))

      def introduce(self):
      # self这个名字可以是任意的,但是通常都是要用这个
      # 既可以访问成员属性
      print('我叫{}'.format(self.name))
      # 也可以访问成员方法
      self.run()


      mugai = Person()
      mugai.name = '木盖'

      # print(mugai)
      mugai.run()

      curry = Person()
      curry.name = '史蒂芬·库里'
      curry.run()

      # 调用方法时第一个参数self不需要传递
      curry.introduce()
    • 说明:

      • 每个成员方法都有这么一个参数,调用的时候不需要传递
      • 名字可以不是 self,只不过通常我们都要 self 而已
      • self 表示当前对象,谁调用该方法就表示谁,哪个对象调用就表示哪个对象
      • 通过 self 可以访问成员属性,也可以调用成员方法
  • __str__方法

    • 示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      class Person:
      # 使用print函数打印时,默认打印对象所属的类型及对象的地址
      # 该函数要求返回一个字符串,当对象作为print参数打印时会打印该字符串
      def __str__(self):
      # 要求返回一个字符串
      return '我叫{},今年{}'.format(self.name, self.age)


      xiaoming = Person()
      xiaoming.name = 'xiaoming'
      xiaoming.age = 18

      print(xiaoming)
    • 练习:

      • 自定义一个狗类,完成属性的动态添加,方法的调用
        • 属性:名字、年龄、颜色
        • 方法:跑、吃、游泳、叫
  • 构造方法

    • 作用:用于对象创建后初始化相关的属性
    • 示例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      class Cat:
      def __init__(self, name, age):
      # 创建对象后进行初始化操作,系统会自动调用
      # 也叫构造方法
      print('init')
      self.name = name
      self.age = age
      self.color = '白色'


      # 创建对象时的参数要与构造方法一致
      tom = Cat('Tom', 1)
      print(tom)
  • 析构方法

    • 作用:当对象即将销毁时,系统会自动调用

    • 示例 1:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      import time


      class Pig:
      def __del__(self):
      # 当对象释放时系统会自动调用,如果你使用del删除对象,则立即释放调用该方法
      # 一般在此处做:断开连接、关闭文件、释放资源等
      print('大师兄,我不行了')


      bajie = Pig()

      # 若删除对象,则会立即调用析构方法
      del bajie

      time.sleep(5)
      bajie.name = 'wuneng'
    • 示例 2:小明手里有两张牌,左手♥K,右手♠A,问:小明交换两手的牌后,手里分别是什么?

    • 思路:

      • 先找到对象:小明、左手、♥K、♠A、右手
      • 根据对象抽象出来的类:人、牌、手
      • 写出对应的逻辑,反过来完善抽象出来的类
      • 按照题目要求创建对应的对象,调用相关的方法
      • 代码:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        # 扑克牌
        class Poker:
        def __init__(self, color, number):
        self.color = color
        self.number = number

        def __str__(self):
        return '{}{}'.format(self.color, self.number)


        # 创建两张牌
        p1 = Poker('♥', 'K')
        p2 = Poker('♠', 'A')


        # 手的类
        class Hand:
        def __init__(self, poker=None):
        self.poker = poker

        def hold_poker(self, poker):
        self.poker = poker


        # 创建左右两只手的对象
        left_hand = Hand(p1)
        right_hand = Hand(p2)


        # 人的类
        class Person:
        def __init__(self, name, left_hand, right_hand):
        self.name = name
        self.left_hand = left_hand
        self.right_hand = right_hand

        # 展示手里的牌
        def show(self):
        print('{}张开手'.format(self.name))
        print('左手:{}'.format(self.left_hand.poker))
        print('右手:{}'.format(self.right_hand.poker))

        # 交换手里的牌
        def swap(self):
        self.left_hand.poker, self.right_hand.poker = self.right_hand.poker, self.left_hand.poker
        print('{}交换两手的牌'.format(self.name))


        # 创建小明对象
        xiaoming = Person('小明', left_hand, right_hand)
        # 展示手里的牌
        xiaoming.show()
        # 小明交换牌
        xiaoming.swap()
        # 再次展示手里的牌
        xiaoming.show()

常见的内置函数

  • 内置函数:在类的内部,特定时机自动触发的函数

  • 示例:setattr、getattrr、delattr

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    class Person:
    # def __init__(self, name):
    # self.name = name

    def __setattr__(self, key, value):
    # 当设置对象成员属性时,系统会自动调用
    print(key, value)
    self.__dict__[key] = value

    def __getattr__(self, item):
    # 当访问不存在的属性时,系统会自动调用
    if item == 'age':
    return 123
    else:
    return 'default'

    def __delattr__(self, item):
    # 当销毁对象的成员属性时,系统会自动调用
    print('del', item)


    xiaoming = Person()

    # 每个对象都有一个成员属性:__dict__
    # 用于存放对象的属性,包括动态添加的
    # print(xiaoming.__dict__)

    # xiaoming.name = '小明'
    # print(xiaoming.name)

    # print(xiaoming.__dict__)

    xiaoming.age = 18

    print(xiaoming.age)
    print(xiaoming.hello)

    del xiaoming.age
    # del xiaoming.hello
  • 练习:

    1
    2
    自己研究:setitem、getitem、delitem
    友情提醒:当将一个对象作为字典操作时,会触发上面对应的方法
------------- 本文结束 感谢您的阅读 -------------
正在加载今日诗词....