1 什么是面向对象?

1.1 常见的编程思想

人们利用计算机来解决实际问题的一种思维方式

编程思想是通用的,与计算机语言本身没有太大关系的。

常见的思维方式有面向过程和面向对象

Python是同时支持面向过程和面向对象的编程语言! A.面向过程:前段学习的思维都是过程; B.面向对象:新思维。

1.2 理解面向对象是什么

1.2.1 面向过程

我们解决问题的时候,会把所需要的步骤都列出来,然后按照步骤写代码挨个实现

这种过程化的叙事思维,就是面向过程思想。

例如: 以 面向过程 形式了解去ATM机取钱
(1) 带上你的银行卡,去ATM机所在的地方;
(2) 排队等待;
(3) 轮到自己了,把银行卡插入ATM机;
(4) 输入密码,取钱;
(5) 取钱成功,准备回去咯。
1.2.2 面向对象

当我们的视角不再是步骤过程,而是另一个视角:操作完整对象

这里的对象可以理解为:冰箱、手机、电脑等一切现实实体事物。

这时候,我们就是使用面向对象思维看待问题了,大家记住五个字一切皆对象

我们来看看这种思维的优点:

  • 使人们的编程与实际的世界更加接近,所有的对象被赋予属性和方法,这样编程就更加富有人性化;

  • 它的宗旨在于模拟现实世界中的概念;

  • 在现实生活中,所有事物全被视为对象。

1.3 面向对象的三大特性

面向对象的三大特性有:封装、继承、多态

1.3.1 封装

在现实生活中,我们身边也是有很多与封装相关的案例。

小明是一个IT公司的公司职员,当他要去银行办理信用卡时,银行需要他提供身份证号、银行卡号、联系方式;在他身边的同事知道他的姓名、职位、性别、年龄等基本信息,小明的爸妈知道他的血型、身份证号、女朋友姓名、性别等等。我们会发现,小明在生活中有很多隐私,其实这就是封装。

小明身边的人信息 了解小明的隐私内容项
银行柜员 身份证号、联系方式、银行卡号等。
同事 姓名、职位、性别、年龄等。
爸妈 血型、身份证号、女朋友姓名、性别等。

在面向对象中,封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别【公有、私有】,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体【类】,也就是将数据与操作数据的源代码进行有机的结合,形成"",其中数据和函数都是类的成员。

封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员。

比如,我们日常生活中的手机、电脑都可以封装为一个类。 一切皆对象!

1.3.2 继承

在现实生活中,继承一般指的是子女继承父辈的财产,如"子承父业"等。

在面向对象中,继承也是面向对象的基本特征之一。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和行为;

或子类从父类继承方法,使得子类具有父类相同的行为。

只要是继承关系,那么都满足:is-a关系。 子类是父类。

1.3.3多态

多态是指不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式

这里的发送消息就是指方法的调用。

【通俗】从一个生活中使用电脑的案例来简要说明什么是多态,比如电脑键盘上的F12功能键是固定不变的。

固定不变的F12功能键 完成功能
F12 在WPS办公软件使用时,提示用户保存文件。
F12 在Chrome浏览器使用时,能进入到开发者模式。
  • 三大概念

    • 封装:把属性和方法封装到类中进行隐藏,对外提供访问接口

    • 继承:子承父业 子类继承父类的属性和方法

    • 多态:同样一个函数在不同的场景下有不同的表现 (多种状态)

2 面向对象的基本概念

2.1面向对象中的重要概念

Python是一门面向对象的语言(也是一门面向过程的语言)。要掌握Python面向对象的基本语法,则首先需要掌握两个重要的概念:类、对象。怎么理解呢?

⚡️类:对现实事物的抽象描述

⚡️对象:现实事物的具体体现

2.2 类

案例描述:我们都知道汽车是由汽车图纸生产出来的,那么此处的汽车图纸就是一个模板(即类),在汽车图纸上,指定规则:生产出来的汽车必须具有跑起来的行为。

在Python中如何创建类呢?需要通过关键字class 来定义类,Python 类的语法格式如下:

# 定义类
class 类名:
    # 定义方法
    方法列表...

案例:定义一个汽车类,并有跑起来的行为。

# 1.定义类:class 类名:
class Car:
    # 2.定义方法:跑起来
    def run(self):
        print('能跑起来...')

对象

案例描述:通过汽车图纸生产出能跑起来的汽车(即对象)。

创建对象的语法格式如下:

对象名 = 类名()    # 创建对象

在实际应用中,创建和使用对象的基本步骤如下:

步骤1:通过上述语法创建一个对象,如下:

对象名 = 类名()

步骤2:可通过对象名.方法来调用方法,如下: 调用行为 ==.== 的

对象名.方法名()       #调用方法

案例:生产一台可以跑起来的车

# 1.定义类:class 类名:
class Car:
    # 1.1.定义方法:跑起来
    def run(self):
        print('能跑起来...')
​
# 2.创建对象:对象名 = 类名()
car = Car()
# 3.调用方法:对象.方法名()
car.run()

执行顺序

2.3 self关键字

self也是Python内置的关键字之一,其指向了对象实例本身【对象自己】。

案例分析

"""
self关键字介绍:
    概述:
        它代表本类当前对象的引用, 一般用于: 函数中, 即: 谁调用这个函数, self就代表谁(哪个对象).
    简单记忆:
        谁(本类对象)调用(函数), self就代表谁.

"""

# 需求1: 创建汽车类Car, 分别创建两个对象, 观察结果.
class Car:
    # 定义行为, 跑.
    def run(self):
        print('汽车会跑!')
        print(f'self: {self}')



# 测试代码一般写到 main方法中.
if __name__ == '__main__':
    # 创建对象.
    c1 = Car()
    c2 = Car()

    # 调用类的成员.
    c1.run()
    c2.run()
    print('-' * 20)

    # 打印对象名
    print(c1)   # <__main__.Car object at 0x000002244653D5E0>
    print(c2)   # <__main__.Car object at 0x000002244653D520>

3.在类内部调用方法:一般用在私有方法上

# 1.定义类:类名使用大驼峰方式命名
class Car():
    def run(self):
        print('能跑起来...')
​
    # 在类内部调用方法:对象名.方法名()->self.方法名()
    def work(self):
        self.run()
​
# 2.定义对象:对象名一般小驼峰命名
car = Car()
​
# 3.调用方法:对象名.方法名()
car.work()
  • 类和对象语法

    class 类名:
        pass
    ​
    对象1 = 类名()
    对象2 = 类名()

  • self关键字

    • 为什么需要self关键字

      • 类和对象的关系1:N ,为了区分那个对象调用了类的方法,引入了self。

      • 谁调用run函数。self就是谁

    • self关键字的作用:

      • 在类的内部,调用类的方法 self.work()

3 添加和获取对象属性

3.1 什么是属性

属性即是特征,比如:人的姓名、年龄、身高、体重…都是对象的属性

3.2 类外面添加和获取属性

3.2.1 添加属性

设置对象中属性是通过"."点来操作的,如下:

对象名.属性 = 属性值
3.2.2 获取属性

在Python中,获取对象属性的方式如下:

对象名.属性

例如,给车设置颜色为红色、4个轮胎,且获取属性值并输出。

"""
案例: 演示在 类外定义 和 获取 属性.

格式:
    添加属性   对象名.属性名 = 属性值
    获取属性   对象名.属性名
"""

# 案例: 定义汽车类, 在类外给汽车对象 设置属性, 颜色=红色, 轮胎 = 4, 获取属性值并打印.


# 1. 定义汽车类.
class Car():
    # 2. 定义 run() 函数.
    def run(self):
        print('汽车会跑!')


# main函数
if __name__ == '__main__':
    # 3. 创建汽车类对象.
    c1 = Car()
    # 4. 调用 行为.
    c1.run()

    # 5. 设置属性.
    c1.color = 'Red'    # 汽车颜色: 红色
    c1.num = 4          # 汽车轮胎数: 4

    # 6. 获取属性.
    print(f'汽车颜色: {c1.color}, 轮胎数: {c1.num}')
    print('-' * 20)

    # 7. 我们再次创建1个汽车对象, 请问: 有上述的 color, num属性吗?
    c2 = Car()
    c2.run()
    print(f'汽车颜色: {c2.color}, 轮胎数: {c2.num}')  # 报错, 无该属性.

3.3 类内部获取对象属性

在类内部获取对象属性的方式,如下:

对象名.属性            
----
self.属性

例如,在类内部定义一个show()方法来获取刚刚给车设置颜色为红色、4个轮胎的属性值信息。

  • 属性:和现实生活中的属性类似

  • 添加属性:

    • 在类的外部

      对象名.属性名 = 4
  • 获取属性

在类的内部: self.属性
在类的外部: 对象.属性
  • 编程思想: 利用计算机解决实际问题的思维方式

    • 面向过程:步骤,扩展性差

    • 面向对象: 一切皆对象

      • 类 :抽象的模板

        # 大驼峰
        class 类名:
            pass
      • 对象:具象的实体

        # 下划线
        对象名 = 类名()
        对象名.方法名()
      • 方法->函数

        定义方法自动填充self,调用方法时不需要传递self
        self: 对象本身,类内部对对象进行操作时要想到self
      • 属性->变量

        对象固有的特征,可以设置获取这些属性
"""
案例:
    演示 在类内部, 通过 self关键字, 访问类内部(自己的) 函数.

细节:
    在类中调用 类的行为(函数), 可以通过 self.的方式 调用.
"""

# 需求: 定义汽车类, 其有 run() 和 work()两个函数, run()表示跑的功能, 在work()函数中调用run()函数, 并在main方法中, 创建对象, 调用并测试.

# 1.定义汽车类
class Car():
    # 2. run()函数, 表示: 跑的行为.
    def run(self):
        print('我是 run 函数')
        print('汽车会跑!')

    # 3. 在work()函数中调用run()函数
    def work(self):
        print('我是 work 函数')
        self.run()      # 类内部, 可以通过 self. 的方式, 调用类的其它成员.


# 在main方法中测试.
if __name__ == '__main__':
    # 4. 创建对象.
    c1 = Car()
    c2 = Car()

    # 5. 调用 run()函数
    c1.run()
    c2.run()
    print('-' * 20)

    # 6. 调用 work()函数
    c1.work()
    c2.work()

5 魔法方法

5.1 魔法方法的概念

在Python中,有一些可以给Python类增加魔力的特殊方法,我们称之为魔法方法。

在特殊情况下会被自动调用,不需要开发者手动去调用。

对于这些魔法方法,都有一个共同的特性,那就是它们总是被双下划线所包围,如下:

__魔法方法名__()

语法:

class 类名:
    def __魔法方法名__(self[,xxx,xxx]):
        代码
        ...
    # ...

5.2 __init__()方法

有没有办法能够在创建对象时,就把车这个对象的属性给设置好呢?

此时,就可以使用__init__()方法(也称为构造方法)了。

在Python中,当新创建一个对象时,则会自动触发__init__()魔法方法。

魔法方法名称 描述信息
__init__(self [, ...]) 当一个实例被创建时调用的初始化方法。
无参数的__init__()方法

无参数情况:当仅需在类内部使用及初始化某些属性时,可以使用,格式如下:

def __init__(self):
    # 初始化属性     对象名.属性 = 属性值
    self.属性 = 属性值
    代码
    ......

例如,给车这个对象默认设置color(颜色)和number(轮胎数)为黑色、3个轮胎。

# 1.定义类
class Car:
    # 1.1 设置属性:__init__
    def __init__(self):
        self.color = 'red'
        self.number = 4
​
    # 1.2 获取属性: self.属性名
    def show(self):
        print(f'车身颜色:{self.color}')
        print(f'车轮数:{self.number}')
​
​
# 2.创建对象:对象名 = 类名()
car = Car()
​
# 2.1 获取属性
# 类内部
car.show()
# 类外部
# print(car.color)
# print(car.number)

"""
案例: 演示魔法方法 init()之 无参数情况.

魔法方法解释:
    概述:
        在Python中, 有一类方法是用来 对Python类的功能做 加强(扩展)的, 且这一类方法都无需手动调用.
        在满足特定情况的场景下, 会被自动调用, 它们就称之为: 魔法方法.
    格式:
        __魔法方法名__()      注意, 这里是两个下划线.
    常用的魔法方法:
        __init__()      用于初始化对象的属性值的, 在创建对象的时候, 会被: 自动调用.           c1 = Car()
        __str__()       用于快速打印对象的各个属性值的, 在输出语句打印对象的时候会自动调用.     print(c1)
        __del__()       当删除对象的时候, 或者main函数执行完毕后, 会自动调用.
"""

# 需求: 给车类的所有对象, 默认设置 颜色为黑色, 轮胎数为3 这两个属性值.
# 场景1: 不使用魔法方法.
# class Car:
#     pass


# 场景2: 使用魔法方法
class Car:      # Python类的命名, 遵循: 大驼峰命名法. 例如: HelloWorld
    # 魔法方法 __init__()完成, 对 属性 的初始化操作.
    def __init__(self):
        self.color = '黑色'
        self.number = 3


# main函数, 一般用于写: 测试代码
if __name__ == '__main__':
    c1 = Car()              # 创建对象, 会自动调用 init()魔法方法
    # 如下的格式就不是 定义属性了, 而是 修改属性值.
    c1.color = '红色'
    c1.number = 4
    print(f'汽车颜色: {c1.color}, 轮胎数: {c1.number}')        # 红色, 4

    c2 = Car()              # 创建对象, 会自动调用 init()魔法方法
    # c2.color = '黑色'
    # c2.number = 3
    print(f'汽车颜色: {c2.color}, 轮胎数: {c2.number}')        # 黑色, 3
有参数的__init__()方法

有参数情况:当需要通过类外部传递相应变量值用于改变某些属性时,可以使用,格式如下:

def __init__(self,参数1,参数2,...):
    代码
    ......
 例如,通过外部给车这个对象设置color(颜色)、number(轮胎数)值。
# 1.定义类
class Car:
    # 1.1 设置属性:__init__
    def __init__(self, color, number):
        self.color = color
        self.number = number
​
    # 1.2 获取属性: self.属性名
    def show(self):
        print(f'车身颜色:{self.color}')
        print(f'车轮数:{self.number}')
​
​
# 2.创建对象:对象名 = 类名()
car = Car('black', 8)
​
# 2.1 获取属性
# 类内部
car.show()
# 类外部
# print(car.color)
# print(car.number)

"""
案例: 演示魔法方法 init()之 无参数情况.

魔法方法解释:
    概述:
        在Python中, 有一类方法是用来 对Python类的功能做 加强(扩展)的, 且这一类方法都无需手动调用.
        在满足特定情况的场景下, 会被自动调用, 它们就称之为: 魔法方法.
    格式:
        __魔法方法名__()      注意, 这里是两个下划线.
    常用的魔法方法:
        __init__()      用于初始化对象的属性值的, 在创建对象的时候, 会被: 自动调用.           c1 = Car()
        __str__()       用于快速打印对象的各个属性值的, 在输出语句打印对象的时候会自动调用.     print(c1)
        __del__()       当删除对象的时候, 或者main函数执行完毕后, 会自动调用.
"""

# 需求: 通过外部给车这个对象设置 color属性, number属性值.
class Car:      # Python类的命名, 遵循: 大驼峰命名法. 例如: HelloWorld
    # 魔法方法 __init__()完成, 对 属性 的初始化操作.
    def __init__(self, color, number):
        self.color = color
        self.number = number


# main函数, 一般用于写: 测试代码
if __name__ == '__main__':
    c1 = Car('黑色', 6)              # 创建对象, 会自动调用 init()魔法方法
    # 如下的格式就不是 定义属性了, 而是 修改属性值.
    c1.color = '红色'
    c1.number = 4
    print(f'汽车颜色: {c1.color}, 轮胎数: {c1.number}')        # 红色, 4

    c2 = Car('霞光紫', 3)                      # 创建对象, 会自动调用 init()魔法方法
    print(f'汽车颜色: {c2.color}, 轮胎数: {c2.number}')       # 霞光紫, 3

5.3 __str__()方法

当使用print输出对象时,默认打印对象的内存地址值【十六进制】。 若要让输出对象名时,不是内存地址值,应该要在类中定义str方法。

如果类定义了__str__方法,那么就会打印从在这个方法中 return的数据。

魔法方法名称 描述信息
__str__(self) 定义当被str()调用时的行为。

语法:

class 类名:
    def __str__(self):
        代码
        ...
        return 值   # 说明:值的类型必须是字符串类型

例如,在输出car对象时,把它的颜色color、轮胎数number属性值显示出来。

# 1,定义类
class Car:
    # 1.1 属性的设置
    def __init__(self):
        self.color = '红色'
        self.number = 4
​
    # 1.2 str:输出属性信息
    def __str__(self):
        # return f'{self.color}的汽车有{self.number}个车轮'
        print(f'{self.color}的汽车有{self.number}个车轮')
​
​
​
# 2.创建对象
car = Car()
​
# 3.打印对象
print(car)
  • 未实现str时输出内存地址

  • 实现str时输出str的返回值

  • 一定要有返回值,返回值必须是字符串类型的

5.4 __del__()方法

当删除对象时,Python解释器也会默认调用__del__()方法。

魔法方法名称 描述信息
__del__(self) 析构器,当一个实例被销毁时调用的方法。

例如,定义一个有品牌属性的车类,并使用__del__()方法删除对象查看效果。

# 1.定义类
class Car:
    # 1.1 属性赋值
    def __init__(self,color):
        self.color = color
​
    # 1.2 del魔法
    def __del__(self):
        print('自动调用了del魔法方法')
​
# 2.创建对象
car = Car('红色')
# 3.获取属性
# print(car.color)
del car
print(car.color)

魔法方法: 与普通方法区别

  • 自动调用,特殊情况下

  • 前后被双下滑线包围

init方法:创建对象时自动调用,用来对对象属性进行赋值

  • 无参(self):在类内部进行属性值的确定

  • 有参: 通过类外部实现属性值的设置

str方法:print(对象)是自动调用,直接输出str方法返回的结果

del方法:删除对象时自动调用

"""
案例: 演示魔法方法 init()之 无参数情况.

魔法方法解释:
    概述:
        在Python中, 有一类方法是用来 对Python类的功能做 加强(扩展)的, 且这一类方法都无需手动调用.
        在满足特定情况的场景下, 会被自动调用, 它们就称之为: 魔法方法.
    格式:
        __魔法方法名__()      注意, 这里是两个下划线.
    常用的魔法方法:
        __init__()      用于初始化对象的属性值的, 在创建对象的时候, 会被: 自动调用.           c1 = Car()
        __str__()       用于快速打印对象的各个属性值的, 在输出语句打印对象的时候会自动调用.     print(c1)
        __del__()       当删除对象的时候, 或者main函数执行完毕后, 会自动调用.
"""

# 需求: 通过外部给车这个对象设置 color属性, number属性值.
class Car:      # Python类的命名, 遵循: 大驼峰命名法. 例如: HelloWorld
    # 魔法方法 __init__()完成, 对 属性 的初始化操作.
    def __init__(self, color, number):
        self.color = color
        self.number = number

    # 魔法方法 __str__(), 输出语句打印对象时, 会自动调用, 一般用于打印对象的 各个属性值.
    def __str__(self):
        return f"汽车颜色: {self.color}, 轮胎数: {self.number}"


    # 魔法方法 __del__(), del删除对象的时候 或者 文件执行结束后, 会自动调用它, 用于: 释放资源.
    def __del__(self):
        print(f'{self} 对象被释放了!')


# main函数, 一般用于写: 测试代码
if __name__ == '__main__':
    c1 = Car('黑色', 6)              # 创建对象, 会自动调用 init()魔法方法

    # 手动打印 对象的属性值, 相对: 较麻烦.
    print(f'汽车颜色: {c1.color}, 轮胎数: {c1.number}')        # 红色, 4
    print(c1)       # 输出语句打印对象, 底层默认调用了 对象的 __str__()魔法方法, 一般我们都会通过 __str__()打印对象的各个属性值.
    print("-" * 20)

    c2 = Car('猛男粉', 8)
    print(c2)
    print("*" * 20)

    # del c1    从内存中, 删除对象c1
    # del c2

6 面向对象的综合案例

6.1 案例:减肥

案例描述:例如,小明同学当前体重是100kg[默认]。

每当他跑步一次时,则会减少0.5kg;

每当他大吃大喝一次时,则会增加2kg。

请试着采用面向对象方式完成案例。

# 1.定义类
class Student:
    # 1.1 属性赋值:weight
    def __init__(self):
        self.weight = 100
​
    # 1.2 run
    def run(self):
        self.weight-=0.5
        print(f'跑步一次之后体重为{self.weight}')
​
    # 1.3 eat
    def eat(self):
        self.weight+=2
        print(f'大吃大喝后体重为{self.weight}')
​
​
# 2.创建对象
xiaoming = Student()
# 3.调用方法
xiaoming.run()
xiaoming.eat()
xiaoming.run()
xiaoming.run()
xiaoming.run()
xiaoming.run()
xiaoming.eat()

6.2 案例:烤地瓜

被烤时间、生熟程度

0-3分钟:生的
3-7分钟:半生不熟
7-12分钟:熟了
超过12分钟:已烤焦,糊了

添加调料

添加的调料:用户可以按自己的意愿添加调料。

需求:涉及了一个事物地瓜,因此从面向对象角度思考就涉及一个类:地瓜类。

# 1.定义类
class SweetPotato:
    # 1.1 初始化属性
    def __init__(self):
        self.cook_time = 0
        self.cook_state = '生的'
        self.condi_list = []
​
    # 1.2 地瓜被烤
    def cook(self,time):
        # 被烤的时间
        self.cook_time +=time
        if 0<=self.cook_time<3:
            self.cook_state = '生的'
        elif 3<=self.cook_time<7:
            self.cook_state = '半生不熟的'
        elif 7<=self.cook_time<12:
            self.cook_state = '熟了'
        elif self.cook_time>12:
            self.cook_state = '烤糊了'
​
    # 1.3 添加调料
    def add_condi(self,condi):
        self.condi_list.append(condi)
​
​
    # 1.4 信息输出
    def __str__(self):
        return f'这个地瓜烤了{self.cook_time},状态是{self.cook_state},添加了{self.condi_list}'
​
​
# 2.创建对象
potato = SweetPotato()
print(potato)
​
# 3.调用方法
potato.cook(3)
potato.add_condi('蜂蜜')
print(potato)
​
​
potato.cook(5)
potato.add_condi('酱油')
print(potato)
​
potato.cook(6)
potato.add_condi('醋')
print(potato)

面向对象编程:

  • 在需求中找实体->对象

  • 把对象抽象为类

  • 在需求中找属性和方法

【上一篇】【Python基础】7.Python 文件,异常,内置模块

【下一篇】【Python进阶】9.面向对象高级

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐