跳转至

面向对象编程

Object Oriented Programming

什么是对象

​ 对象是指现实生活中的物体或实体

什么是面向对象

​ 把一切看成对象,用各种对象之间的关系来描述事物

对象的特征

  1. 对象有很多属性(名词或形容词) 年龄,姓名,性别...
  2. 对象有很多行为(动作,动词) 学习,吃饭,睡觉,踢球,工作...

什么是类

  • 拥有相同属性个行为的对象分为一组,即为一个类
  • 类是用来描述对象的工具,用类可以创建此类的对象(实例)

类的创建语句

class 语句

    语法
        class 类名(继承列表)
            '''类文档字符串'''
            实例方法定义
            类变量定义
            类方法定义(@classmethod)
            静态方法定义(@staticmethod)

    作用
        创建一个类
        类用于描述对象的行为和属性
        类用于创建此类的一个或多个对象(实例)
    说明
        类名必须为标识符(与变量命名规则相同,建议首字母大写)
        类名实质上就是变量,它绑定一个类
class Dog():
    '''创建一个Dog类,此类用于描述一种小动物的行为和属性'''
    pass

dog1 = Dog()  # 创建Dog类的一个实例
print(id(dog1))

dog2 = Dog()  # 创建Dog类的一个实例
print(id(dog2))

构造函数

    构造函数调用表达式
        类名([创建传参列表])

    作用
        创建这个类的对象,并返回此实例对象的引用关系

    说明
        实例有自己的作用域和名字空间,可以为该实例添加实例变量(也叫属性)
        实例可以调用类方法和实例方法
        实例可以访问类变量和实例变量

实例方法(method)

    语法
        class 类名(继承列表):
            def 实例方法名(self, 形参名1, 形参名2, ...):
                '''方法文档字符串'''
                语句块

    作用
        用于描述一个对象的行为,让此类型的全部对象都拥有相同的行为

    说明
        实例方法的实质是函数,是定义在类内的函数
        实例方法至少有一个形参,第一个形参用来绑定调用这个方法的实例,一般命名为'self'

实例方法的调用语句

    实例.实例方法名(调用传参)
    或
    类名.实例方法名(实例, 调用传参)
# 此示例示意示例方法的定义和调用
class Dog:
    def eat(self, food):
        '''此方法用来描述小狗吃东西的行为'''
        print('小狗正在吃', food)
    def sleep(self, hour):
        print('小狗睡了%d小时' % hour)
    def play(self, obj):
        print('小狗正玩', obj)

dog = Dog()
dog.eat('骨头')
dog.sleep(1)
dog.play('飞盘')

实例属性 attribute

    每个实例可以有自己的实例变量用来保存对象自己的数据

    语法
        实例.属性名

    赋值规则同变量的赋值规则
        首次为属性赋值则创建此属性
        再次为属性赋值则改变属性的绑定关系

    作用
        记录每个对象自身的数据
# 此示例示意示例的属性attribute 及访问属性的方法
class Dog:
    def eat(self, food):
        self.last_food = food
        print(self.color, '的', self.kinds, '正在吃', food)
    def show_last_food(self):
        print(self.color, '的', self.kinds,'上次吃的', self.last_food)

dog1 = Dog()
dog1.kinds = '京巴'  # 添加实例属性
dog1.color = '白色'  # 添加狗毛的颜色
dog1.color = '黄色'  # 修改实例属性的绑定关系

dog2 = Dog()
dog2.kinds = '藏獒'  # 另一个对象
dog2.color = '棕色'
print(dog1.color, '的', dog1.kinds)
print(dog2.color, '的', dog2.kinds)

dog1.eat('骨头')
dog2.eat('狗粮')
dog1.show_last_food()
dog2.show_last_food()
练习
    定义一个'人'(Human)
        calss Human:
            def set_info(self, name, age, address='不详')
                '''此方法用来给人对象添加姓名, 年龄, 家庭住址等属性'''

            def show_info(self):
                '''此处显示此人信息'''
    调用如下
        h1 = Human()
        h1.set_info('小张', 20, '北京市东城区')
        h2 = Human()
        h2.set_info('小李', 18)
        h1.show_info()
        h2.show_info()

删除属性

    del 语句
        可以删除实例(instance)的属性
    语句
        del 实例.实例变量名
    示例
        class Dog:
            pass
        dog1 = Dog()
        dog1.color = '白色'
        del dog1.color  # 删除属性
        print(dog1.color)  # AttributeError 属性错误

del语句小结

  1. 删除变量 del name
  2. 删除列表中的元素 del l[0]
  3. 删除字典的键 del d['name']
  4. 删除实例的属性 del 实例.实例变量名

初始化方法

    作用
        对新创建的对象添加属性
    语法格式
        class 类名(继承列表):
            del __init__(self, [形参列表]):
                语句块

        注: []代表其中的内容可以省略

    说明
        1. 初始化方法名必须为 '__init__' 不可以改变
        2. 初始化方法会在构造函数创建实例后自动调用,且将实例自身通过第一个参数self 传入__init__方法
        3. 构造函数的实参将通过__init__方法的参数列表传入到__init__方法中
        4. 初始化方法内如果需要return语句返回,则只能返回None
# 此示例示意初始化方法的定义,及初始化方法对新对象添加属性
class Car:
    def __init__(self, c, b, m):
        self.color = c  # 颜色
        self.brand = b  # 品牌
        self.model = m  # 型号
    def run(self, speed):
        print(self.color, '的', self.brand, self.model, '正在以', speed, '公里/小时的速度行驶')

a4 = Car('红色','奥迪','A4')
a4.run(199)

t1 = Car('蓝色', 'TESLA', 'Model S')
t1.run(230)
练习
写一个Student类, 此类创建的对象有三个属性,姓名,年龄, 成绩
    1. 用初始化方法为该类添加上述三个属性
    2. 添加set_score() 方法能为对象修改学生成绩
    3. 添加show_info() 方法打印学生信息

析构方法

class 类名(继承列表):
    def __del__(self):
        语句块
析构方法在对象被销毁时自动调用
python语言建议不要在对象销毁时做任何事,因为销毁时间难以确定

```python

此示例示意析构方法的使用

import time class Car: def init(self, info): self.info = info print('汽车对象', info, '被创建') def del(self): print('汽车对象', self.info, '被销毁') car = Car('BYD E6')

car = None # 改变对象的绑定关系可以释放 BYD E6对象

del car # 删除变量释放对象 l = [] l.append(Car('汽车1')) l.append(Car('汽车2')) l.append(Car('汽车3'))

del l # 释放列表

input('请输入回车键继续执行程序') print('程序退出') ```

预置实例属性

__dict__属性
        __dict__属性 绑定一个存储此实例自身变量字典

    示例
        class Dog:
            pass
        dog1 = Dog()
        print(dog1.__dict__)  # {}
        dog1.color = '白色'
        print(dog1.__dict__)  # {'color': '白色'}
        dog1.kinds = '京巴'
        print(dog1.__dict__)  # {'color': '白色', 'kinds':'京巴'}

__class__属性
        __class__ 属性绑定创建此实例的类
        作用
            可以借助此属性来访问创建此实例的类
        示例
            class Dog:
                pass
            dog1 = Dog()
            print(dog1.__class__)
            dog2 = dog1.__class__()
            print(dog2.__class__)

用于对象的函数

isinstance(obj, class_or_tuple)
    返回这个对象obj是否是某个类的对象或者某些类中的一个类的对象,如果是返回True, 否则返回False

    type(obj)  返回对象的类型

面向对象的综合示例

有两个人:
        属性:
            1. 姓名:张三    年龄:35 岁
            2. 姓名:李四    年龄:8  岁
        行为:
            1. 教别人学东西 teach
            2. 工作赚钱 work
            2. 工作赚钱 work
            3. 借钱 borrow
    事情:
        张三 教 李四 学 python
        李四 教 张三 学 王者荣耀
        张三 上班赚了 1000元钱
        李四 向 张三 借了 200元钱
        35 岁的 张三 有钱 800元, 它学会的技能:王者荣耀
        8  岁的 李四 有钱 200元, 它学会的技能:python

类变量

类变量是类的属性,此属性属于类,不属于此类的实例

    作用
        通常用来存储该类创建对象的共有属性

    说明
        类变量可以通过该类直接访问
        类变量,可以通过类的实例直接访问
        类变量可以通过此类的对象__class__属性间接访问

类的文档字符串

类内第一个没有赋值给任何变量的字符串为类的文档字符串
    类的文档字符串可以通过help()函

    数查看
    类的文档字符串绑定在类的__doc__属性上
类的__slots__列表
    作用
        限定一个类创建的实例只能有固定的属性(实例变量)
        不允许对象添加列表以外的实例属性(实例变量)
        防止用户因填错属性名而发生的程序错误
    说明
        __slots__属性绑定一个字符串列表
        含有__slots__属性的类所创建的实例对象没有__dict__属性,即此实例不用字典来存储对象的实例属性
# 此示例示意类内__slots__列表的用法和作用
class Human:
    # __slots__ = ['name', 'age']  # 保存类只能有列表里的属性
    def __init__(self, n, a):
        self.name = n
        self.age = a
    def info(self):
        print(self.name, '今年', self.age, '岁')

h1 = Human('小张', 8)
h1.info()  # 小张 今年 8 岁
h1.Age = 9
h1.info()  # 小张 今年 8 岁

类方法@classmethod

类方法是用于描述类的行为的方法,类方法属于类,不属于类的实例对象

    说明
        类方法需要用@calssmethod装饰器定义
        类方法至少有一个形参,第一个形参绑定类,约定为'cls'
        类和该类的实例都可以调用类的方法
        类方法不能访问此类创建的对象的实例属性

    示例见
        class A:
            v = 0  # 类变量

            @classmethod
            def get_v(cls):
                return cls.v  # 用cls访问变量v

            @classmethod
            def set_v(cls, v):
                cls.v = v

        A.set_v(100)
        print('A.v =', A.get_v())  # 调用类方法得到类变量的值

        a = A()  # a绑定大A类型的一个实例对象
      【 print(a.get_v())  # 此类的实例也能调用该类的方法, 实际上传递的是a.__class__,装饰器的功能 】

静态方法 @staticmethod

静态方法是定义在类的内部的函数,此函数的作用域是类的内部
    说明
        静态方法是需要使用@staticmethod装饰器定义
        静态方法与普通函数定义相同,不需要传入self实际参数和cls类参数
        静态方法只能凭借该类或类创建的实例调用
        静态方法不能访问类变量和实例变量