面向对象编程

📋 个人简介
💖 作者简介:大家好,我是W_chuanqi,一个编程爱好者
📙 个人主页:W_chaunqi
😀 支持我:点赞👍+收藏⭐️+留言📝
💬 愿你我共勉:“若身在泥潭,心也在泥潭,则满眼望去均是泥潭;若身在泥潭,而心系鲲鹏,则能见九万里天地。”✨✨✨

在这里插入图片描述

一、面向对象基础

1.理解面向对象

​ Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。

  • 面向过程: 分析出解决问题所需要的步骤,然后用函数把这些步骤一一实现,使用的时候依次调用就可以了。

  • 面向对象: 把构成问题的事务按照一定规则划分为多个独立的对象,然后通过调用对象的方法来解决问题。

​ 面向对象是一种符合人类思维习惯的编程思想。现实生活中存在各种形态不同的事物,这些事物之间存在着各种各样的联系。在程序中使用对象映射现实中的事物,使用对象的关系描述事物之间的联系,这种思想就是面向对象。

2.面向对象具有三大特性

2.1 封装性

​ 封装是面向对象的核心思想,它有两层含义,一是指把对象的属性和行为看成是一个密不可分的整体,将这两者“封装”在一起(即封装在对象中);另外一层含义指“信息隐藏”,将不想让外界知道的信息隐藏起来。例如,驾校的学员学开车,只需要知道如何操作汽车,无需知道汽车内部是如何工作的。

2.2 继承性

​ 继承性主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。例如,有一个汽车类,该类描述了汽车的普通特性和功能。进一步再产生轿车类,而轿车类中不仅应该包含汽车的特性和功能,还应该增加轿车特有的功能,这时,可以让轿车类继承汽车类,在轿车类中单独添加轿车特性和方法就可以了。继承不仅增强了代码的复用性、提高开发效率,还降低了程序产生错误的可能性,为程序的维护以及扩展提供了便利。

2.3 多态性

​ 多态性指的是在一个类中定义的属性和方法被其它类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。例如,当听到“Cut” 这个单词时,理发师的行为是剪发,演员的行为表现是停止表演,不同的对象,所表现的行为是不一样的。多态的特性使程序更抽象、便捷,有助于开发人员设计程序时分组协同开发。

​ 在面向对象中,为了做到让程序对事物的描述与事物在现实中的形态保持一致,面向对象思想中提出了两个概念,即类和对象。

3.类和对象

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

3.1理解类和对象

3.1.1类

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

  • 特征即是属性
  • ⾏为即是⽅法

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

image-20220704181526556

3.1.2对象

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

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

image-20220704183641602

3.2 ⾯向对象实现⽅法

3.2.1定义类

✳语法

class 类名():
 代码
 ......

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

✳体验

class Washer():
	def wash(self):
 		print('我会洗⾐服')
3.2.2 创建对象

对象⼜名实例。

✳语法

对象名 = 类名()

✳体验

# 创建对象
haier1 = Washer()
# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)
# haier对象调⽤实例⽅法
haier1.wash()

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

3.2.3 self

self指的是调⽤该函数的对象。

# 1. 定义类
class Washer():
	def wash(self):
		print('我会洗⾐服')
		# <__main__.Washer object at 0x0000024BA2B34240>
		print(self)

# 2. 创建对象
haier1 = Washer()
# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)
# haier1对象调⽤实例⽅法
haier1.wash()
haier2 = Washer()
# <__main__.Washer object at 0x0000022005857EF0>
print(haier2) 

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

4.添加和获取对象属性

​ 属性即是特征,⽐如:洗⾐机的宽度、⾼度、重量…

​ 对象属性既可以在类外⾯添加和获取,也能在类⾥⾯添加和获取。

4.1 类外⾯添加对象属性

✳语法

对象名.属性名 =

✳体验

haier1.width = 500
haier1.height = 800

4.2 类外⾯获取对象属性

✳语法

对象名.属性名

✳实例

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

4.3类里面获取对象属性

✳语法

self.属性名

✳实例

# 定义类
class Washer():
 	def print_info(self):
 	# 类⾥⾯获取实例属性
 	print(f'haier1洗⾐机的宽度是{self.width}')
 	print(f'haier1洗⾐机的⾼度是{self.height}')
    
# 创建对象
haier1 = Washer()
# 添加实例属性
haier1.width = 500
haier1.height = 800
haier1.print_info()

5.类属性和实例属性

5.1 类属性

5.1.1设置和访问类属性
  • 类属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有
  • 类属性可以使⽤ 类对象实例对象 访问。
class Dog(object):
	tooth = 10

wangcai = Dog()
xiaohei = Dog()

print(Dog.tooth) # 10
print(wangcai.tooth) # 10
print(xiaohei.tooth) # 10

类属性的优点

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

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

class Dog(object):
	tooth = 10

wangcai = Dog()
xiaohei = Dog()

# 修改类属性
Dog.tooth = 12
print(Dog.tooth) # 12
print(wangcai.tooth) # 12
print(xiaohei.tooth) # 12

# 不能通过对象修改属性,如果这样操作,实则是创建了⼀个实例属性
wangcai.tooth = 20
print(Dog.tooth) # 12
print(wangcai.tooth) # 20
print(xiaohei.tooth) # 12

5.2 实例属性

class Dog(object):

    def __init__(self):
        self.age = 5

    def info_print(self):
        print(self.age)


wangcai = Dog()
print(wangcai.age)  # 5
# print(Dog.age) # 报错:实例属性不能通过类访问
wangcai.info_print()  # 5

6.类⽅法和静态⽅法

6.1 类⽅法

6.1.1 类⽅法特点
  • 第⼀个形参是类对象的⽅法
  • 需要⽤装饰器 @classmethod 来标识其为类⽅法,对于类⽅法,第⼀个参数必须是类对象,⼀般以cls 作为第⼀个参数。
6.1.2 类⽅法使⽤场景
  • 当⽅法中 需要使⽤类对象 (如访问私有类属性等)时,定义类⽅法
  • 类⽅法⼀般和类属性配合使⽤
class Dog(object):
	__tooth = 10

	@classmethod
	def get_tooth(cls):
		return cls.__tooth

wangcai = Dog()
result = wangcai.get_tooth()
print(result) # 10

6.2 静态⽅法

6.2.1 静态⽅法特点
  • 需要通过装饰器 @staticmethod 来进⾏修饰,静态⽅法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。
  • 静态⽅法 也能够通过 实例对象类对象 去访问。
6.2.2 静态⽅法使⽤场景
  • 当⽅法中 既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类⽅法、创建实例等)时,定义静态⽅法
  • 取消不需要的参数传递,有利于 减少不必要的内存占⽤和性能消耗
class Dog(object):
	@staticmethod
	def info_print():
		print('这是⼀个狗类,⽤于创建狗实例....')
        
wangcai = Dog()
# 静态⽅法既可以使⽤对象访问⼜可以使⽤类访问
wangcai.info_print()
Dog.info_print()

7.魔法⽅法

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

方法作用
_init_构造函数,在生成对象时调用
_del_析构函数,释放对象时使用
_repr_打印,转换
_setitem_按照索引赋值
_getitem_按照索引获取值
_len_获得长度
_cmp_比较运算
_call_函数调用
_add_加运算
_sub_减运算
_mul_乘运算
_truediv_除运算
_mod_求余运算
_pow_乘方

7.1_init_()

7.1.1体验 _init_()

_init_() ⽅法的作⽤:初始化对象

class Washer():

 	# 定义初始化功能的函数
 	def __init__(self):
 		# 添加实例属性
 		self.width = 500
 		self.height = 800

	def print_info(self):
 		# 类⾥⾯调⽤实例属性
		print(f'洗⾐机的宽度是{self.width}, ⾼度是{self.height}')
     
haier1 = Washer()
haier1.print_info()

注意:

_init_() ⽅法,在创建⼀个对象时默认被调⽤,不需要⼿动调⽤

_init_(self) 中的self参数,不需要开发者传递,python解释器会⾃动把当前的对象引⽤传递过去。

7.1.2 带参数的_init_()
class Washer():

	def __init__(self, width, height):
		self.width = width
		self.height = height

	def print_info(self):
		print(f'洗⾐机的宽度是{self.width}')
		print(f'洗⾐机的⾼度是{self.height}')

haier1 = Washer(10, 20)
haier1.print_info()
haier2 = Washer(30, 40)
haier2.print_info()

7.2__str__()

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

class Washer():

	def __init__(self, width, height):
 		self.width = width
 		self.height = height

 	def __str__(self):
 		return '这是海尔洗⾐机的说明书'

haier1 = Washer(10, 20)
# 这是海尔洗⾐机的说明书
print(haier1)

7.3_del_()

当删除对象时,python解释器也会默认调⽤ del() ⽅法。

class Washer():

	def __init__(self, width, height):
		self.width = width
		self.height = height

	def __del__(self):
		print(f'{self}对象已经被删除')

haier1 = Washer(10, 20)
# <__main__.Washer object at 0x0000026118223278>对象已经被删除
del haier1

8.综合运用

8.1 烤地⽠

8.1.1需求

需求主线:

  1. 被烤的时间和对应的地⽠状态:
  • 0-3分钟:⽣的
  • 3-5分钟:半⽣不熟
  • 5-8分钟:熟的
  • 超过8分钟:烤糊了
  1. 添加的调料:⽤户可以按⾃⼰的意愿添加调料
8.1.2步骤分析

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

1.定义类

  • 地⽠的属性
    • 被烤的时间
    • 地⽠的状态
    • 添加的调料
  • 地⽠的⽅法
    • 被烤
      • ⽤户根据意愿设定每次烤地⽠的时间
      • 判断地⽠被烤的总时间是在哪个区间,修改地⽠状态
    • 添加调料
      • ⽤户根据意愿设定添加的调料
      • 将⽤户添加的调料存储
  • 显示对象信息

2.创建对象,调⽤相关实例

8.1.3代码实现
# 定义类
class SweetPotato():

	def __init__(self):
 		# 被烤的时间
 		self.cook_time = 0
		# 地⽠的状态
 		self.cook_static = '⽣的'
 		# 调料列表
		self.condiments = []

	def cook(self, time):
 	"""烤地⽠的⽅法"""
    	self.cook_time += time
		if 0 <= self.cook_time < 3:
			self.cook_static = '⽣的'
		elif 3 <= self.cook_time < 5:
			self.cook_static = '半⽣不熟'
		elif 5 <= self.cook_time < 8:
			self.cook_static = '熟了'
		elif self.cook_time >= 8:
			self.cook_static = '烤糊了'
 
	def add_condiments(self, condiment):
	"""添加调料"""
		self.condiments.append(condiment)

	def __str__(self):
    	return f'这个地⽠烤了{self.cook_time}分钟, 状态是{self.cook_static}, 添加的调料有{self.condiments}'
    
digua1 = SweetPotato()
print(digua1)

digua1.cook(2)
digua1.add_condiments('酱油')
print(digua1)

digua1.cook(2)
digua1.add_condiments('辣椒⾯⼉')
print(digua1)

digua1.cook(2)
print(digua1)

digua1.cook(2)
print(digua1)

8.2 搬家具

8.2.1需求

将⼩于房⼦剩余⾯积的家具摆放到房⼦中

8.2.2步骤分析

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

1.定义类

  • 房⼦类
    • 实例属性
      • 房⼦地理位置
      • 房⼦占地⾯积
      • 房⼦剩余⾯积
      • 房⼦内家具列表
    • 实例⽅法
      • 容纳家具
      • 显示房屋信息
  • 家具类
    • 家具名称
    • 家具占地⾯积

2.创建对象并调⽤相关⽅法

8.2.3代码实现
#家具类
class Furniture():

	def __init__(self, name, area):
		# 家具名字
		self.name = name
		# 家具占地⾯积
		self.area = area

#房子类
class Home():
	def __init__(self, address, area):
		# 地理位置
		self.address = address
		# 房屋⾯积
		self.area = area
		# 剩余⾯积
		self.free_area = area
		# 家具列表
        self.furniture = []
 
	def __str__(self):
		return f'房⼦坐落于{self.address}, 占地⾯积{self.area}, 剩余⾯积{self.free_area}, 家具有{self.furniture}'
 
	def add_furniture(self, item):
	"""容纳家具"""
		if self.free_area >= item.area:
			self.furniture.append(item.name)
			# 家具搬⼊后,房屋剩余⾯积 = 之前剩余⾯积 - 该家具⾯积
			self.free_area -= item.area
		else:
			print('家具太⼤,剩余⾯积不⾜,⽆法容纳')

bed = Furniture('双⼈床', 6)
jia1 = Home('北京', 1200)
print(jia1)

jia1.add_furniture(bed)
print(jia1)

sofa = Furniture('沙发', 10)
jia1.add_furniture(sofa)
print(jia1)

ball = Furniture('篮球场', 1500)
jia1.add_furniture(ball)
print(jia1)

二、继承

1.继承的概念

⽣活中的继承,⼀般指的是⼦⼥继承⽗辈的财产。

image-20220711214749091

# ⽗类A
class A(object):
	def __init__(self):
		self.num = 1
 
	def info_print(self):
		print(self.num)

# ⼦类B
class B(A):
	pass

result = B()
result.info_print() # 1

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

2.单继承

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

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

# 1. 师⽗类
class Master(object):
 
	def __init__(self):
		self.kongfu = '[古法煎饼果⼦配⽅]'
	def make_cake(self):
		print(f'运⽤{self.kongfu}制作煎饼果⼦')
 
# 2. 徒弟类
class Prentice(Master):
	pass

# 3. 创建对象daqiu
daqiu = Prentice()
# 4. 对象访问实例属性
print(daqiu.kongfu)
# 5. 对象调⽤实例⽅法
daqiu.make_cake()

3.多继承

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

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

class Master(object):
	def __init__(self):
 		self.kongfu = '[古法煎饼果⼦配⽅]'
	def make_cake(self):
 		print(f'运⽤{self.kongfu}制作煎饼果⼦')

# 创建学校类
class School(object):
 	def __init__(self):
		self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
 	def make_cake(self):
 		print(f'运⽤{self.kongfu}制作煎饼果⼦')

class Prentice(School, Master):
	pass

daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()

注意:当⼀个类有多个⽗类的时候,默认使⽤第⼀个⽗类的同名属性和⽅法。

4.⼦类重写⽗类的同名属性和⽅法

故事:daqiu掌握了师⽗和培训的技术后,⾃⼰潜⼼钻研出⾃⼰的独⻔配⽅的⼀套全新的煎饼果⼦技术。

class Master(object):
	def __init__(self):
    	self.kongfu = '[古法煎饼果⼦配⽅]'
    
	def make_cake(self):
		print(f'运⽤{self.kongfu}制作煎饼果⼦')
 
class School(object):
	def __init__(self):
		self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
 
	def make_cake(self):
		print(f'运⽤{self.kongfu}制作煎饼果⼦')
 
# 独创配⽅
class Prentice(School, Master):
	def __init__(self):
		self.kongfu = '[独创煎饼果⼦配⽅]'
	def make_cake(self):
		print(f'运⽤{self.kongfu}制作煎饼果⼦')

daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
print(Prentice.__mro__) 

⼦类和⽗类具有同名属性和⽅法,默认使⽤⼦类的同名属性和⽅法。

5.⼦类调⽤⽗类的同名属性和⽅法

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

class Master(object):
	def __init__(self):
		self.kongfu = '[古法煎饼果⼦配⽅]'
	def make_cake(self):
		print(f'运⽤{self.kongfu}制作煎饼果⼦')

class School(object):
	def __init__(self):
		self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
    def make_cake(self):
		print(f'运⽤{self.kongfu}制作煎饼果⼦')

class Prentice(School, Master):
	def __init__(self):
		self.kongfu = '[独创煎饼果⼦配⽅]'
	def make_cake(self):
 		# 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化
 		self.__init__()
 		print(f'运⽤{self.kongfu}制作煎饼果⼦')

	# 调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化
	def make_master_cake(self):
		Master.__init__(self)
		Master.make_cake(self)
	def make_school_cake(self):
		School.__init__(self)
		School.make_cake(self)

daqiu = Prentice()
daqiu.make_cake()
daqiu.make_master_cake()
daqiu.make_school_cake()
daqiu.make_cake()

6.多层继承

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

class Master(object):
	def __init__(self):
	    self.kongfu = '[古法煎饼果⼦配⽅]'
    
    def make_cake(self):
        print(f'运⽤{self.kongfu}制作煎饼果⼦')


class School(object):
    def __init__(self):
        self.kongfu = '[⿊⻢煎饼果⼦配⽅]'
    def make_cake(self):
        print(f'运⽤{self.kongfu}制作煎饼果⼦')


class Prentice(School, Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果⼦配⽅]'
    def make_cake(self):
        self.__init__()
        print(f'运⽤{self.kongfu}制作煎饼果⼦')
    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)
    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

# 徒孙类
class Tusun(Prentice):
    pass


xiaoqiu = Tusun()
xiaoqiu.make_cake()
xiaoqiu.make_school_cake()
xiaoqiu.make_master_cake()

7.super()调用父类方法

class Master(object):

    def __init__(self):

        self.kongfu = '[古法煎饼果⼦配⽅]'

    def make_cake(self):

        print(f'运⽤{self.kongfu}制作煎饼果⼦')


class School(Master):

    def __init__(self):

        self.kongfu = '[⿊⻢煎饼果⼦配⽅]'

    def make_cake(self):

        print(f'运⽤{self.kongfu}制作煎饼果⼦')
        # ⽅法2.1
        # super(School, self).__init__()
        # super(School, self).make_cake()
        # ⽅法2.2
        super().__init__()
        super().make_cake()


class Prentice(School):

    def __init__(self):
        self.kongfu = '[独创煎饼果⼦技术]'

    def make_cake(self):
        self.__init__()
        print(f'运⽤{self.kongfu}制作煎饼果⼦')

    # ⼦类调⽤⽗类的同名⽅法和属性:把⽗类的同名属性和⽅法再次封装
    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):

        School.__init__(self)
        School.make_cake(self)

     # ⼀次性调⽤⽗类的同名属性和⽅法
    def make_old_cake(self):

        # ⽅法⼀:代码冗余;⽗类类名如果变化,这⾥代码需要频繁修改
        # Master.__init__(self)
        # Master.make_cake(self)
        # School.__init__(self)
        # School.make_cake(self)

        # ⽅法⼆: super()
        # ⽅法2.1 super(当前类名, self).函数()
        # super(Prentice, self).__init__()
        # super(Prentice, self).make_cake()
        # ⽅法2.2 super().函数()
        super().__init__()
        super().make_cake()


daqiu = Prentice()
daqiu.make_old_cake()

注意:使⽤super() 可以⾃动查找⽗类。调⽤顺序遵循 mro 类属性的顺序。⽐较适合单继承使⽤。

8.私有权限

8.1定义私有属性和方法

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

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

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

class Master(object):
    def __init__(self):
        self.kongfu = '[古法煎饼果⼦配⽅]'

    def make_cake(self):
        print(f'运⽤{self.kongfu}制作煎饼果⼦')


class School(object):
    def __init__(self):
        self.kongfu = '[⿊⻢煎饼果⼦配⽅]'

    def make_cake(self):
        print(f'运⽤{self.kongfu}制作煎饼果⼦')


class Prentice(School, Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果⼦配⽅]'
        # 定义私有属性
        self.__money = 2000000

    # 定义私有⽅法
    def __info_print(self):
        print(self.kongfu)
        print(self.__money)

    def make_cake(self):
        self.__init__()
        print(f'运⽤{self.kongfu}制作煎饼果⼦')

    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

# 徒孙类
class Tusun(Prentice):
    pass


daqiu = Prentice()
# 对象不能访问私有属性和私有⽅法
# print(daqiu.__money)
# daqiu.__info_print()
xiaoqiu = Tusun()
# ⼦类⽆法继承⽗类的私有属性和私有⽅法
# print(xiaoqiu.__money) # ⽆法访问实例属性__money
# xiaoqiu.__info_print()

注意:私有属性和私有⽅法只能在类⾥⾯访问和修改。

8.2获取和修改私有属性值

class Master(object):
    def __init__(self):
        self.kongfu = '[古法煎饼果⼦配⽅]'

    def make_cake(self):
        print(f'运⽤{self.kongfu}制作煎饼果⼦')


class School(object):

    def __init__(self):
        self.kongfu = '[⿊⻢煎饼果⼦配⽅]'

    def make_cake(self):
        print(f'运⽤{self.kongfu}制作煎饼果⼦')


class Prentice(School, Master):

    def __init__(self):
        self.kongfu = '[独创煎饼果⼦配⽅]'
        self.__money = 2000000
    # 获取私有属性

    def get_money(self):
        return self.__money
    # 修改私有属性

    def set_money(self):
        self.__money = 500

    def __info_print(self):
        print(self.kongfu)
        print(self.__money)

    def make_cake(self):
        self.__init__()
        print(f'运⽤{self.kongfu}制作煎饼果⼦')

    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)
# 徒孙类


class Tusun(Prentice):
    pass


daqiu = Prentice()
xiaoqiu = Tusun()
# 调⽤get_money函数获取私有属性money的值
print(xiaoqiu.get_money())
# 调⽤set_money函数修改私有属性money的值
xiaoqiu.set_money()
print(xiaoqiu.get_money())

三、其他概念

1.多态

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

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

    def work(self):  # ⽗类提供统⼀的⽅法,哪怕是空⽅法
        print('指哪打哪...')


class ArmyDog(Dog):  # 继承Dog类
    def work(self):  # ⼦类重写⽗类同名⽅法
        print('追击敌⼈...')


class DrugDog(Dog):
    def work(self):
        print('追查毒品...')


class Person(object):
    def work_with_dog(self, dog):  # 传⼊不同的对象,执⾏不同的代码,即不同的work函数
        dog.work()


ad = ArmyDog()
dd = DrugDog()
daqiu = Person()
daqiu.work_with_dog(ad)
daqiu.work_with_dog(dd)

2.运算符重载

​ Python同样支持运算符重载,我们可以对类的专有方法进行重载,实例如下:

#!/usr/bin/python3
 
class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b
 
   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)
 
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

以上代码执行结果如下所示:

image-20220630124758919

3.抽象类

3.1 抽象类概念

  • 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化,需要借助python模块实现;
  • 抽象类是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性;
  • 抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。

3.2 python中的abc模块

​ python中需要利用abc模块实现抽象类


import abc #利用abc模块实现抽象类

class shuiguo(metaclass=abc.ABCMeta):
    
    all_type='sg'

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def name(self):
        pass

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def func(self):
        pass


class Apple(shuiguo): #子类继承抽象类,可是必须定义read和write方法
    def name(self):
        print('我是苹果')

    def func(self):
        print('好吃')

class Pear(shuiguo): #子类继承抽象类,可是必须定义read和write方法
    def name(self):
        print('我是梨子')

    def func(self):
        print('yunfeizhike')


apple =Apple()

pear=Pear()

apple.func()
pear.name()

print(pear.all_type)
print(apple.all_type)

注意:

  • 抽象类的本质仍是类,指的是一组类的类似性,包括数据属性(如all_type)和函数属性;
  • 抽象类是一个介于类和接口之间的一个概念,同时具有类和接口的部分特性

4.获取对象的信息

  • python中有几个内置方法,可以用来检查或是访问对象的属性。这些方法可以用于任意对象;
  • dir([obj]):调用这个方法将返回包含obj大多数属性名的列表(会有一些特殊的属性不包含在内)。obj的默认值是当前的模块对象。
  • hasattr(obj, attr):这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。
  • getattr(obj, attr):调用这个方法将返回obj中名为attr值的属性的值,
  • setattr(obj, attr, val):调用这个方法将给obj的名为attr的值的属性赋值为val。
  • type(obj):判断对象类型,使用type()函数
class Pear(): 
    def name(self):
        print('我是梨子')

    def func(self):
        print('yunfeizhike')

import types
p = Pear()

print(dir(p))
print(type(p))
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W_chuanqi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值