Python进阶编程:面向对象编程
Python进阶编程:面向对象编程
面向对象
根据B站大学
和廖雪峰的python
整理而来
什么是面向对象
面向过程:思考的重点在于步骤。
面向对象:把问题分解成各个对象,描述对象在整个事情的行为。
引子
人狗大战
先创建很多狗,每个狗有各自的名字,品种,攻击力等
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# 面向过程的思考
dog1 = {
"name": "小红", # 创建dog1
"d_type": "京巴",
"attack_val": 40
}
def bite1(person): # dog1咬人
person.life_val -= 40
dog2 = {"name": "小明", # 创建dog2
"d_type": "牧羊犬",
"attack_val": 50
}
def bite2(person): # dog2咬人
person.life_val -= 50
print(dog1)
print(dog2)
#以此类推创建dog3,doe4......
#可以看到每当创建一个dog3就要重复很多代码,很是麻烦,有没有更好的办法的呢?
#很负责任的跟大家说—— 没有
#是不可能的!!
#下面就是另一种编程思想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# 面向对象的思考
#写一个函数,包含了每个狗的共同点
attack_vals = {
"京巴":40,
"牧羊犬":50,
"藏獒":60
}
def dog(name, d_type):
data = {
"name": name,
"d_type": d_type,
"life_val": 80
}
if d_type in attack_vals: # 根据品种添加攻击力
data["attack_val"] = attack_vals[d_type]
return data
dog1 = dog("小红", "京巴") # 实体1
dog2 = dog("小明", "牧羊犬") # 实体2
print(dog1)
print(dog2)
创建很多人
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#人也按照共同点创造
def person(name, age):
data = {
"name": name,
"age": age,
"life_val": 100
}
if age > 18:
data["attack_val"] = 50
else:
data["attack_val"] = 20
return data
P1 = person("阿福", 21)
P2 = person("小璇", 17)
P3 = person("小岚", 21)
P4 = person("小乐", 21)
print(P1)
print(P2)
print(P3)
print(P4)
人可以打狗,狗可以打人
1
2
3
4
5
6
7
8#狗咬人
def bite(dog_obj,person_obj):
print(f"{dog_obj['name']}的攻击力:{dog_obj['attack_val']}")
print(f"{person_obj['name']}的血量:{person_obj['life_val']} ")
person_obj['life_val'] -= dog_obj['attack_val']
print(f"{dog_obj['name']}咬了{person_obj['name']},人掉了{dog_obj['attack_val']}血量,还剩下{person_obj['life_val']}")
bite(dog1,P1)1
2
3
4
5
6
7
8
9#打狗
def fight_dog(person_obj,dog_obj):
print(f"{person_obj['name']}的攻击力:{person_obj['attack_val']}")
print(f"{dog_obj['name']}的血量:{dog_obj['life_val']} ")
dog_obj['life_val'] -= person_obj['attack_val']
print(f"{person_obj['name']}打了{dog_obj['name']},狗子没有了{person_obj['attack_val']}血量,还剩下{dog_obj['life_val']}")
print()
fight_dog(P1,dog1)思考
1
2
3
4上文的打狗函数是bite(dog_obj,person_obj),我们在实际传参的时候写成bite(person_obj,dog_obj)可以吗?
从现实的角度来说,肯定是不可以的。因为bite()函数的狗咬人,理应传入狗的伤害值和人的生命值。
但是从程序的角度来说,这样运行也没什么问题,因为计算机不知道你是人是狗。
那么怎么让计算机知道你是人是狗呢?这就是这篇文章探讨的主要内容了!
类
类的语法
语法格式: class 类的名称():
1 | class dog(): #创建一个狗类 |
类的初始化
1 | class dog(): #创建一个狗类 |
类属性的应用场景
类属性:类变量,也就是公共属性,所有实列共享
实例属性:实例变量,成员变量,每个实例独享
1 | #类属性和实例调用类属性,若数值也是一样,内存空间是一样的 |
dog.life_val变量是一样,都是100,所以可以单独设置
1 | class dog(): #创建一个狗类 |
实列属性对自己不满意也可以改属性
1 | #dog.life_val = 100 |
类之间的关系
- 依赖关系
- 关联关系
- 组合关系
- 聚合关系
- 继承关系,类的三大特性之一
访问限制
访问保护
在类的应用场景我们说到实例属性对自己不满意也可以改属性。
如果要让内部属性不被外部访问,可以在属性前面加上一些东西,如__
需要注意:变量名__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。
1 | class dog(): #创建一个狗类 |
如果说我们有时候真的需要修改life_val怎么办?可以给dog增加一个set_life_val
方法:
1 | class dog(): #创建一个狗类 |
除了修改,我们还需要访问life_val。但是现在显然是不能访问的,解决方案如下:
1 | def set_life_val(self): |
继承
当我们新定义一个class,可以从现有的class继承,新的这个class也就是子类。
比如我们定义一个二哈继承狗类。
1 | class erha(dog): |
这样的话,二哈拥有父类dog的全部功能。
获取对象信息
使用type()
使用type()可以判断类型
1 | type(12345) |
使用isinstance()
对于class的继承关系。使用type()
不方便。
1 | isinstance(erha1,erha) |
因为erha
是从dog
继承下来的,所以erha1也是属于dog
1 | isinstance(erha1,dog) |
使用dir()
获取一个对象的所有属性和方法,它返回一个包含字符串的list。
1 | >>>dir(123) |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 道坤!
评论