【Python】面向对象

前端之家收集整理的这篇文章主要介绍了【Python】面向对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

面向对象基础

一. 理解面向对象

面向对象是一种抽象化的编程思想,很多编程语言中都有的一种思想。
例如:洗⾐服
思考:⼏种途径可以完成洗⾐服?
答: 手洗 和 机洗。
手洗:找盆 - 放⽔ - 加洗⾐粉 - 浸泡 - 搓洗 - 拧⼲⽔ - 倒⽔ - 漂洗N次 - 拧⼲ - 晾晒。
机洗:打开洗⾐机 - 放⾐服 - 加洗⾐粉 - 按下开始按钮 - 晾晒。

思考:对比两种洗⾐服途径,同学们发现了什么?
答:机洗更简单
思考:机洗,只需要找到一台洗⾐机,加入简单操作就可以完成洗⾐服的工作,而不需要关心洗⾐机内部发生了什么事情。

总结:面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况。而编程就是设置事物能够做什么事。

二. 类和对象

思考:洗⾐机洗⾐服描述过程中,洗⾐机其实就是一个事物,即对象,洗⾐机对象哪来的呢?
答:洗⾐机是由工⼚工人制作出来。

思考:工⼚工人怎么制作出的洗⾐机?
答:工人根据设计师设计的功能图纸制作洗⾐机。

总结:图纸 → 洗⾐机 → 洗⾐服。

在面向对象编程过程中,有两个重要组成部分:类 和 对象。
类和对象的关系:用类去创建一个对象。

2.1 理解类和对象

2.1.1 类

类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。

类比如是制造洗⾐机时要用到的图纸,也就是说类是用来创建对象。

2.1.2 对象

对象是类创建出来的真实存在的事物,例如:洗⾐机。

注意:开发中,先有类,再有对象。

2.2 面向对象实现方法

2.2.1 定义类

Python2中类分为:经典类 和 新式类

语法

  1. class 类名():
  2. 代码
  3. ......

注意:类名要满足标识符命名规则,同时遵循大驼峰命名习惯。

体验

  1. class Washer():
  2. def wash(self):
  3. print('我会洗⾐服')

拓展:经典类
不由任意内置类型派生出的类,称之为经典类

  1. class 类名:
  2. 代码
  3. ......

2.2.2 创建对象

对象又名实例。

语法

  1. 对象名 = 类名()

体验

  1. # 创建对象
  2. haier1 = Washer()
  3. # <__main__.Washer object at 0x0000018B7B224240>
  4. print(haier1)
  5. # haier对象调用实例方法
  6. haier1.wash()

注意:创建对象的过程也叫实例化对象。

2.2.3 self

self指的是调用函数的对象。

  1. # 1. 定义类
  2. class Washer():
  3. def wash(self):
  4. print('我会洗⾐服')
  5. # <__main__.Washer object at 0x0000024BA2B34240>
  6. print(self)
  7. # 2. 创建对象
  8. haier1 = Washer()
  9. # <__main__.Washer object at 0x0000018B7B224240>
  10. print(haier1)
  11. # haier1对象调用实例方法
  12. haier1.wash()
  13. haier2 = Washer()
  14. # <__main__.Washer object at 0x0000022005857EF0>
  15. print(haier2)

注意:打印对象和self得到的结果是一致的,都是当前对象的内存中存储地址。

三. 添加获取对象属性

属性即是特征,比如:洗⾐机的宽度、高度、重量...
对象属性既可以在类外面添加获取,也能在类里面添加获取

3.1 类外面添加对象属性

语法

  1. 对象名.属性 =

体验

  1. haier1.width = 500
  2. haier1.height = 800

3.2 类外面获取对象属性

语法

  1. 对象名.属性

体验

  1. print(f'haier1洗⾐机的宽度是{haier1.width}')
  2. print(f'haier1洗⾐机的高度是{haier1.height}')

3.3 类里面获取对象属性

语法

  1. self.属性

体验

  1. # 定义类
  2. class Washer():
  3. def print_info(self):
  4. # 类里面获取实例属性
  5. print(f'haier1洗⾐机的宽度是{self.width}')
  6. print(f'haier1洗⾐机的高度是{self.height}')
  7. # 创建对象
  8. haier1 = Washer()
  9. # 添加实例属性
  10. haier1.width = 500
  11. haier1.height = 800
  12. haier1.print_info()

四. 魔法方法

在Python中, __xx__() 的函数叫做魔法方法,指的是具有特殊功能函数

4.1 __init__()

4.1.1 体验__init__()

思考:洗⾐机的宽度高度是与生俱来的属性,可不可以在生产过程中就赋予这些属性呢?
答:理应如此。

__init__() 方法的作用:初始化对象。

  1. class Washer():
  2. # 定义初始化功能函数
  3. def __init__(self):
  4. # 添加实例属性
  5. self.width = 500
  6. self.height = 800
  7. def print_info(self):
  8. # 类里面调用实例属性
  9. print(f'洗⾐机的宽度是{self.width},高度是{self.height}')
  10. haier1 = Washer()
  11. haier1.print_info()

注意:

  • __init__() 方法,在创建一个对象时默认被调用,不需要手动调用
  • __init__(self) 中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。

4.1.2 带参数的__init__()

思考:一个类可以创建多个对象,如何对不同的对象设置不同的初始化属性呢?
答:传参数。

  1. class Washer():
  2. def __init__(self,width,height):
  3. self.width = width
  4. self.height = height
  5. def print_info(self):
  6. print(f'洗⾐机的宽度是{self.width}')
  7. print(f'洗⾐机的高度是{self.height}')
  8. haier1 = Washer(10,20)
  9. haier1.print_info()
  10. haier2 = Washer(30,40)
  11. haier2.print_info()

4.2 __str__()

当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了 __str__ 方法,那么就会打印从在这个方法中 return 的数据。

  1. class Washer():
  2. def __init__(self,height):
  3. self.width = width
  4. self.height = height
  5. def __str__(self):
  6. return '这是海尔洗⾐机的说明书'
  7. haier1 = Washer(10,20)
  8. # 这是海尔洗⾐机的说明书
  9. print(haier1)

4.3 __del__()

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

  1. class Washer():
  2. def __init__(self,height):
  3. self.width = width
  4. self.height = height
  5. def __del__(self):
  6. print(f'{self}对象已经被删除')
  7. haier1 = Washer(10,20)
  8. # <__main__.Washer object at 0x0000026118223278>对象已经被删除
  9. del haier1

五. 综合应用

5.1 烤地⽠

5.1.1 需求

需求主线:

  1. 被烤的时间和对应的地⽠状态:
    0-3分钟:生的
    3-5分钟:半生不熟
    5-8分钟:熟的
    超过8分钟:烤糊了
  2. 添加的调料:
    用户可以按自己的意愿添加调料

5.1.2 步骤分析

需求涉及一个事物: 地⽠,故案例涉及一个类:地⽠类。

5.1.2.1 定义类
5.1.2.2 创建对象,调用相关实例方法

5.1.3 代码实现

5.1.3.1 定义类

地⽠属性
定义地⽠初始化属性,后期根据程序推进更新实例属性

  1. class SweetPotato():
  2. def __init__(self):
  3. # 被烤的时间
  4. self.cook_time = 0
  5. # 地⽠的状态
  6. self.cook_static = '生的'
  7. # 调料列表
  8. self.condiments = []
5.1.3.2 定义烤地⽠方法
  1. class SweetPotato():
  2. ......
  3. def cook(self,time):
  4. """烤地⽠的方法"""
  5. self.cook_time += time
  6. if 0 <= self.cook_time < 3:
  7. self.cook_static = '生的'
  8. elif 3 <= self.cook_time < 5:
  9. self.cook_static = '半生不熟'
  10. elif 5 <= self.cook_time < 8:
  11. self.cook_static = '熟了'
  12. elif self.cook_time >= 8:
  13. self.cook_static = '烤糊了'
5.1.3.3 书写str魔法方法,用于输出对象状态
  1. class SweetPotato():
  2. ......
  3. def __str__(self):
  4. return f'这个地⽠烤了{self.cook_time}分钟,状态是{self.cook_static}'
5.1.3.4 创建对象,测试实例属性和实例方法
  1. digua1 = SweetPotato()
  2. print(digua1)
  3. digua1.cook(2)
  4. print(digua1)
5.1.3.5 定义添加调料方法,并调用该实例方法
  1. class SweetPotato():
  2. ......
  3. def add_condiments(self,condiment):
  4. """添加调料"""
  5. self.condiments.append(condiment)
  6. def __str__(self):
  7. return f'这个地⽠烤了{self.cook_time}分钟,状态是{self.cook_static},添加的调料有{self.condiments}'
  8. digua1 = SweetPotato()
  9. print(digua1)
  10. digua1.cook(2)
  11. digua1.add_condiments('酱油')
  12. print(digua1)
  13. digua1.cook(2)
  14. digua1.add_condiments('辣椒面儿')
  15. print(digua1)
  16. digua1.cook(2)
  17. print(digua1)
  18. digua1.cook(2)
  19. print(digua1)

5.1.4 代码总览

  1. # 定义类
  2. class SweetPotato():
  3. def __init__(self):
  4. # 被烤的时间
  5. self.cook_time = 0
  6. # 地⽠的状态
  7. self.cook_static = '生的'
  8. # 调料列表
  9. self.condiments = []
  10. def cook(self,time):
  11. """烤地⽠的方法"""
  12. self.cook_time += time
  13. if 0 <= self.cook_time < 3:
  14. self.cook_static = '生的'
  15. elif 3 <= self.cook_time < 5:
  16. self.cook_static = '半生不熟'
  17. elif 5 <= self.cook_time < 8:
  18. self.cook_static = '熟了'
  19. elif self.cook_time >= 8:
  20. self.cook_static = '烤糊了'
  21. def add_condiments(self,添加的调料有{self.condiments}'
  22. digua1 = SweetPotato()
  23. print(digua1)
  24. digua1.cook(2)
  25. digua1.add_condiments('酱油')
  26. print(digua1)
  27. digua1.cook(2)
  28. digua1.add_condiments('辣椒面儿')
  29. print(digua1)
  30. digua1.cook(2)
  31. print(digua1)
  32. digua1.cook(2)
  33. print(digua1)

5.2 搬家具

5.2.1 需求

将小于房子剩余面积的家具摆放到房子中

5.2.2 步骤分析

需求涉及两个事物:房子 和 家具,故被案例涉及两个类:房子类 和 家具类。

5.2.2.1 定义类
  • 房子类
    • 实例属性
      • 房子地理位置
      • 房子占地面积
      • 房子剩余面积
      • 房子内家具列表
    • 实例方法
      • 容纳家具
    • 显示房屋信息
  • 家具类
    • 家具名称
    • 家具占地面积
5.2.2.2 创建对象并调用相关方法

5.2.3 代码实现

5.2.3.1 定义类

家具类

  1. class Furniture():
  2. def __init__(self,name,area):
  3. # 家具名字
  4. self.name = name
  5. # 家具占地面积
  6. self.area = area

房子类

  1. class Home():
  2. def __init__(self,address,area):
  3. # 地理位置
  4. self.address = address
  5. # 房屋面积
  6. self.area = area
  7. # 剩余面积
  8. self.free_area = area
  9. # 家具列表
  10. self.furniture = []
  11. def __str__(self):
  12. return f'房子坐落于{self.address},占地面积{self.area},剩余面积{self.free_area},家具有{self.furniture}'
  13. def add_furniture(self,item):
  14. """容纳家具"""
  15. if self.free_area >= item.area:
  16. self.furniture.append(item.name)
  17. # 家具搬入后,房屋剩余面积 = 之前剩余面积 - 该家具面积
  18. self.free_area -= item.area
  19. else:
  20. print('家具太大,剩余面积不足,无法容纳')
5.2.3.2 创建对象并调用实例属性方法
  1. bed = Furniture('双人床',6)
  2. jia1 = Home('北京',1200)
  3. print(jia1)
  4. jia1.add_furniture(bed)
  5. print(jia1)
  6. sofa = Furniture('沙发',10)
  7. jia1.add_furniture(sofa)
  8. print(jia1)
  9. ball = Furniture('篮球场',1500)
  10. jia1.add_furniture(ball)
  11. print(jia1)

面向对象-继承

一. 继承的概念

生活中的继承,一般指的是子女继承⽗辈的财产。

拓展1:经典类或旧式类
不由任意内置类型派生出的类,称之为经典类。

  1. class 类名:
  2. 代码
  3. ......

拓展2:新式类

  1. class 类名(object):
  2. 代码

Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承⽗类的所有属性方法,具体如下:

  1. # ⽗类A
  2. class A(object):
  3. def __init__(self):
  4. self.num = 1
  5. def info_print(self):
  6. print(self.num)
  7. # 子类B
  8. class B(A):
  9. pass
  10. result = B()
  11. result.info_print() # 1

在Python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫做派生类。

二. 单继承

故事主线:一个煎饼果子⽼师傅,在煎饼果子界摸爬滚打多年,研发了一套精湛的摊煎饼果子的技术。师⽗要把这套技术传授给他的唯一的最得意的徒弟。

分析:徒弟是不是要继承师⽗的所有技术?

  1. # 1. 师⽗类
  2. class Master(object):
  3. def __init__(self):
  4. self.kongfu = '[古法煎饼果子配方]'
  5. def make_cake(self):
  6. print(f'运用{self.kongfu}制作煎饼果子')
  7. # 2. 徒弟类
  8. class Prentice(Master):
  9. pass
  10. # 3. 创建对象daqiu
  11. daqiu = Prentice()
  12. # 4. 对象访问实例属性
  13. print(daqiu.kongfu)
  14. # 5. 对象调用实例方法
  15. daqiu.make_cake()

三. 多继承

故事推进:daqiu是个爱学习的好孩子,想学习更多的煎饼果子技术,于是,在百度搜索到程序员,报班学习煎饼果子技术。

所谓多继承意思就是一个类同时继承了多个⽗类。

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果子配方]'
  4. def make_cake(self):
  5. print(f'运用{self.kongfu}制作煎饼果子')
  6. # 创建学校类
  7. class School(object):
  8. def __init__(self):
  9. self.kongfu = '[⿊⻢煎饼果子配方]'
  10. def make_cake(self):
  11. print(f'运用{self.kongfu}制作煎饼果子')
  12. class Prentice(School,Master):
  13. pass
  14. daqiu = Prentice()
  15. print(daqiu.kongfu)
  16. daqiu.make_cake()

注意:当一个类有多个⽗类的时候,默认使用第一个⽗类的同名属性方法

四. 子类重写⽗类同名方法属性

故事:daqiu掌握了师⽗和培训的技术后,自己潜心钻研出自己的独门配方的一套全新的煎饼果子技术。

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果子配方]'
  4. def make_cake(self):
  5. print(f'运用{self.kongfu}制作煎饼果子')
  6. class School(object):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果子配方]'
  9. def make_cake(self):
  10. print(f'运用{self.kongfu}制作煎饼果子')
  11. # 独创配方
  12. class Prentice(School,Master):
  13. def __init__(self):
  14. self.kongfu = '[独创煎饼果子配方]'
  15. def make_cake(self):
  16. print(f'运用{self.kongfu}制作煎饼果子')
  17. daqiu = Prentice()
  18. print(daqiu.kongfu)
  19. daqiu.make_cake()
  20. print(Prentice.__mro__)

子类和⽗类具有同名属性方法,默认使用子类的同名属性方法

五. 子类调用⽗类的同名方法属性

故事:很多顾客都希望也能吃到古法和⿊⻢的技术的煎饼果子。

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果子配方]'
  4. def make_cake(self):
  5. print(f'运用{self.kongfu}制作煎饼果子')
  6. class School(object):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果子配方]'
  9. def make_cake(self):
  10. print(f'运用{self.kongfu}制作煎饼果子')
  11. class Prentice(School,Master):
  12. def __init__(self):
  13. self.kongfu = '[独创煎饼果子配方]'
  14. def make_cake(self):
  15. # 如果是先调用了⽗类的属性方法,⽗类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
  16. self.__init__()
  17. print(f'运用{self.kongfu}制作煎饼果子')
  18. # 调用⽗类方法,但是为保证调用到的也是⽗类的属性,必须在调用方法调用⽗类的初始化
  19. def make_master_cake(self):
  20. Master.__init__(self)
  21. Master.make_cake(self)
  22. def make_school_cake(self):
  23. School.__init__(self)
  24. School.make_cake(self)
  25. daqiu = Prentice()
  26. daqiu.make_cake()
  27. daqiu.make_master_cake()
  28. daqiu.make_school_cake()
  29. daqiu.make_cake()

六. 多层继承

故事:N年后,daqiu⽼了,想要把所有技术传承给自己的徒弟。

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果子配方]'
  4. def make_cake(self):
  5. print(f'运用{self.kongfu}制作煎饼果子')
  6. class School(object):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果子配方]'
  9. def make_cake(self):
  10. print(f'运用{self.kongfu}制作煎饼果子')
  11. class Prentice(School,Master):
  12. def __init__(self):
  13. self.kongfu = '[独创煎饼果子配方]'
  14. def make_cake(self):
  15. self.__init__()
  16. print(f'运用{self.kongfu}制作煎饼果子')
  17. def make_master_cake(self):
  18. Master.__init__(self)
  19. Master.make_cake(self)
  20. def make_school_cake(self):
  21. School.__init__(self)
  22. School.make_cake(self)
  23. # 徒孙类
  24. class Tusun(Prentice):
  25. pass
  26. xiaoqiu = Tusun()
  27. xiaoqiu.make_cake()
  28. xiaoqiu.make_school_cake()
  29. xiaoqiu.make_master_cake()

七. super()调用⽗类方法

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果子配方]'
  4. def make_cake(self):
  5. print(f'运用{self.kongfu}制作煎饼果子')
  6. class School(Master):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果子配方]'
  9. def make_cake(self):
  10. print(f'运用{self.kongfu}制作煎饼果子')
  11. # 方法2.1
  12. # super(School,self).__init__()
  13. # super(School,self).make_cake()
  14. # 方法2.2
  15. super().__init__()
  16. super().make_cake()
  17. class Prentice(School):
  18. def __init__(self):
  19. self.kongfu = '[独创煎饼果子技术]'
  20. def make_cake(self):
  21. self.__init__()
  22. print(f'运用{self.kongfu}制作煎饼果子')
  23. # 子类调用⽗类的同名方法属性:把⽗类的同名属性方法再次封装
  24. def make_master_cake(self):
  25. Master.__init__(self)
  26. Master.make_cake(self)
  27. def make_school_cake(self):
  28. School.__init__(self)
  29. School.make_cake(self)
  30. # 一次性调用⽗类的同名属性方法
  31. def make_old_cake(self):
  32. # 方法一:代码冗余;⽗类类名如果变化,这里代码需要频繁修改
  33. # Master.__init__(self)
  34. # Master.make_cake(self)
  35. # School.__init__(self)
  36. # School.make_cake(self)
  37. # 方法二: super()
  38. # 方法2.1 super(当前类名,self).函数()
  39. # super(Prentice,self).__init__()
  40. # super(Prentice,self).make_cake()
  41. # 方法2.2 super().函数()
  42. super().__init__()
  43. super().make_cake()
  44. daqiu = Prentice()
  45. daqiu.make_old_cake()

注意:使用super() 可以自动查找⽗类。调用顺序遵循 __mro__ 类属性的顺序。比较适合单继承使用。

八. 私有权限

8.1 定义私有属性方法

在Python中,可以为实例属性方法设置私有权限,即设置某个实例属性或实例方法不继承给子类。

故事:daqiu把技术传承给徒弟的同时,不想把自己的钱(2000000个亿)继承给徒弟,这个时候就要为 钱 这个实例属性设置私有权限。

设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __。

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果子配方]'
  4. def make_cake(self):
  5. print(f'运用{self.kongfu}制作煎饼果子')
  6. class School(object):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果子配方]'
  9. def make_cake(self):
  10. print(f'运用{self.kongfu}制作煎饼果子')
  11. class Prentice(School,Master):
  12. def __init__(self):
  13. self.kongfu = '[独创煎饼果子配方]'
  14. # 定义私有属性
  15. self.__money = 2000000
  16. # 定义私有方法
  17. def __info_print(self):
  18. print(self.kongfu)
  19. print(self.__money)
  20. def make_cake(self):
  21. self.__init__()
  22. print(f'运用{self.kongfu}制作煎饼果子')
  23. def make_master_cake(self):
  24. Master.__init__(self)
  25. Master.make_cake(self)
  26. def make_school_cake(self):
  27. School.__init__(self)
  28. School.make_cake(self)
  29. # 徒孙类
  30. class Tusun(Prentice):
  31. pass
  32. daqiu = Prentice()
  33. # 对象不能访问私有属性和私有方法
  34. # print(daqiu.__money)
  35. # daqiu.__info_print()
  36. xiaoqiu = Tusun()
  37. # 子类无法继承⽗类的私有属性和私有方法
  38. # print(xiaoqiu.__money) # 无法访问实例属性__money
  39. # xiaoqiu.__info_print()

注意:私有属性和私有方法只能在类里面访问和修改

8.2 获取修改私有属性

在Python中,一般定义函数名 get_xx 用来获取私有属性,定义 set_xx 用来修改私有属性值。

  1. class Master(object):
  2. def __init__(self):
  3. self.kongfu = '[古法煎饼果子配方]'
  4. def make_cake(self):
  5. print(f'运用{self.kongfu}制作煎饼果子')
  6. class School(object):
  7. def __init__(self):
  8. self.kongfu = '[⿊⻢煎饼果子配方]'
  9. def make_cake(self):
  10. print(f'运用{self.kongfu}制作煎饼果子')
  11. class Prentice(School,Master):
  12. def __init__(self):
  13. self.kongfu = '[独创煎饼果子配方]'
  14. self.__money = 2000000
  15. # 获取私有属性
  16. def get_money(self):
  17. return self.__money
  18. # 修改私有属性
  19. def set_money(self):
  20. self.__money = 500
  21. def __info_print(self):
  22. print(self.kongfu)
  23. print(self.__money)
  24. def make_cake(self):
  25. self.__init__()
  26. print(f'运用{self.kongfu}制作煎饼果子')
  27. def make_master_cake(self):
  28. Master.__init__(self)
  29. Master.make_cake(self)
  30. def make_school_cake(self):
  31. School.__init__(self)
  32. School.make_cake(self)
  33. # 徒孙类
  34. class Tusun(Prentice):
  35. pass
  36. daqiu = Prentice()
  37. xiaoqiu = Tusun()
  38. # 调用get_money函数获取私有属性money的值
  39. print(xiaoqiu.get_money())
  40. # 调用set_money函数修改私有属性money的值
  41. xiaoqiu.set_money()
  42. print(xiaoqiu.get_money())

面向对象-其他

一. 面向对象三大特性

二. 多态

2.1 了解多态

多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)。

  • 定义:多态是一种使用对象的方式,子类重写⽗类方法调用不同子类对象的相同⽗类方法,可以产生不同的执行结果
  • 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化!
  • 实现步骤:
    • 定义⽗类,并提供公共方法
    • 定义子类,并重写⽗类方法
    • 传递子类对象给调用者,可以看到不同子类执行效果不同

2.2 体验多态

  1. class Dog(object):
  2. def work(self): # ⽗类提供统一的方法,哪怕是空方法
  3. print('指哪打哪...')
  4. class ArmyDog(Dog): # 继承Dog类
  5. def work(self): # 子类重写⽗类同名方法
  6. print('追击敌人...')
  7. class DrugDog(Dog):
  8. def work(self):
  9. print('追查毒品...')
  10. class Person(object):
  11. def work_with_dog(self,dog): # 传入不同的对象,执行不同的代码,即不同的work函数
  12. dog.work()
  13. ad = ArmyDog()
  14. dd = DrugDog()
  15. daqiu = Person()
  16. daqiu.work_with_dog(ad)
  17. daqiu.work_with_dog(dd)

三. 类属性和实例属性

3.1 类属性

3.1.1 设置和访问类属性

  • 属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有。
  • 属性可以使用 类对象 或 实例对象 访问。
  1. class Dog(object):
  2. tooth = 10
  3. wangcai = Dog()
  4. xiaohei = Dog()
  5. print(Dog.tooth) # 10
  6. print(wangcai.tooth) # 10
  7. print(xiaohei.tooth) # 10

属性的优点

  • 类的实例 记录的某项数据 始终保持一致时,则定义类属性
  • 实例属性 要求 每个对象 为其 单独开辟一份内存空间 来记录数据,而 类属性 为全类所共有,仅占用一份内存,更加节省内存空间。

3.1.2 修改属性

属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改属性,表示的是创建了一个实例属性

  1. class Dog(object):
  2. tooth = 10
  3. wangcai = Dog()
  4. xiaohei = Dog()
  5. # 修改属性
  6. Dog.tooth = 12
  7. print(Dog.tooth) # 12
  8. print(wangcai.tooth) # 12
  9. print(xiaohei.tooth) # 12
  10. # 不能通过对象修改属性,如果这样操作,实则是创建了一个实例属性
  11. wangcai.tooth = 20
  12. print(Dog.tooth) # 12
  13. print(wangcai.tooth) # 20
  14. print(xiaohei.tooth) # 12

3.2 实例属性

  1. class Dog(object):
  2. def __init__(self):
  3. self.age = 5
  4. def info_print(self):
  5. print(self.age)
  6. wangcai = Dog()
  7. print(wangcai.age) # 5
  8. # print(Dog.age) # 报错:实例属性不能通过类访问
  9. wangcai.info_print() # 5

四. 类方法和静态方法

4.1 类方法

4.1.1 类方法特点

  • 第一个形参是类对象的方法
  • 需要用装饰器 @classmethod 来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以 cls 作为第一个参数。

4.1.2 类方法使用场景

  1. class Dog(object):
  2. __tooth = 10
  3. @classmethod
  4. def get_tooth(cls):
  5. return cls.__tooth
  6. wangcai = Dog()
  7. result = wangcai.get_tooth()
  8. print(result) # 10

4.2 静态方法

4.2.1 静态方法特点

  • 需要通过装饰器 @staticmethod 来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。
  • 静态方法 也能够通过 实例对象 和 类对象 去访问。

4.2.2 静态方法使用场景

  • 方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象 (如类属性、类方法、创建实例等)时,定义静态方法
  • 取消不需要的参数传递,有利于 减少不必要的内存占用和性能消耗
  1. class Dog(object):
  2. @staticmethod
  3. def info_print():
  4. print('这是一个狗类,用于创建狗实例....')
  5. wangcai = Dog()
  6. # 静态方法既可以使用对象访问又可以使用类访问
  7. wangcai.info_print()
  8. Dog.info_print()

猜你在找的Python相关文章