Python 的面向对象和其他语言不一样,python的class术语与c++有一定区别,与 Modula-3更像。
1 设计面向对象
设计分成下面的两个方面,一定要先设计,找好对象,找类
1 面向对象程序设计 OOD
- 找对象-->找类(归纳对象共同的特征和技能,每个对象独有的特征)
2面向对象程序编程OOP
- 先定义类--实例化对象
1.1 面向对象的作用
可扩展性性强,增加属性,但是导致了可控性差。
1.2 什么是对象,什么是类
python中一切皆为对象,且python3统一了类与类型的概念,类型就是类。如dict
用面向对象设计一个游戏,每个玩家所有一个英雄,每个英雄都有自己的特征和技能,特征和技能的结合体就是一个对象。
从一组对象中提取相似的部分就是类,类是所有对象的都具有的特征和技能的结合体。
python 中用变量表示特征,用函数表示技能,所以类是变量和函数的结合体,对象是变量与方法(指向类的函数)的结合体
2 初识类
class Data:
pass
Python3中的都是新式类,新式类必须继承至少一个父类
2.1 类的使用
属性引用和实例化
1 属性引用(类名.属性)
class Student:
county = 'China' # 共有的特征
def __init__(self,ID,NAME,SEX,PROVINCE): # 一个人独有的特征
self.id = ID
self.name = NAME
self.sex = SEX
self.province = PROVINCE
def search_score(self):
print("tell score")
def study(self):
print('study',self)
```python
Student.county #引用类的数据属性,该属性与所有对象/实例共享
2 **实例化(__init__与self)**
类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征
>>>s1 = Student('121231','aaa','female','beijing') # 默认的self
self的作用是在实例化时自动将对象/实例本身传给__init__的第一个参数
实例化后就能够通过s1.的方式进行调用
2.2 对象 (实例)
对象是关于类而实际存在的一个例子,即实例。
print(isinstance(s1,Student)) # s1 是Student的实例
2.2.1对象(实例)只有一种作用,就是属性引用
对象和实例本身只有数据属性
print(s1.id)
print(s1.nickname)
2.2.2绑定方法
对象(实例)本身只有数据属性,但是Python的class机制会把类的函数绑定到对象上,叫做对象的方法,或者绑定方法,
绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址不一样。
print(s1.search_score) # 对象的绑定方法
bound method Student.search_score of <main.Student object at 0x00000000028F46A0
print(Student.search_score) # 对象的绑定方法search_score实际是类的函数的功能,两者是一种绑定关系
function Student.search_score at 0x00000000028EBBF8
对象的绑定方法的特别之处在于:obj.func()会把obj传给func的第一个参数。
就是把s1传递给了Stdent类
绑定方法是唯一绑定到一个对象身上,不是共享的
2.2.3 对象之间的交互
class Riven:
camp = 'Noxus'
def __init__(self,nickname,agressiviry=54,life_value=114):
self.nick = nickname
self.agre= agressiviry
self.life_value = life_value
def attack(self,enemy):
print("%s is attack %s" %(self.nick,enemy))
enemy.life_value -=self.agre# 根据自己的攻击力,攻击敌人,敌人的生命值就会减少
class Garen:
camp = 'Noxus'
def __init__(self,nickname,agressiviry=54,life_value=114):
self.nick = nickname
self.agre = agressiviry
self.life_value = life_value
def attack(self,enemy):
print("%s is attack %s" %(self.nick,enemy))
enemy.life_value -=self.agre # 根据自己的攻击力,攻击敌人,敌人的生命值就会减少
#实例化一个Riven
r1 = Riven("aaa") # 实例化一个Riven
g1 = Garen("bbb") # 实例化一个Garen
# print(g1.life_value) #
# print(g1.nickname)
# print(g1.agressivity)
g1.attack(r1) # 交互式攻击 g1攻击g2
print(r1.life_value) # 好看敌人的生命值已经减少
2.3 类的名称空间与对象(实例)的名称空间
类的名称空间
创建一个类的名称空间,用来存储类的中定义的名字,这些名字称为类的属性。
类有两种属性:数据属性和函数属性
类的数据属性是共享给所有对象的
print(id(r1.camp)) #本质就是在引用类的camp属性,二者id一样
print(id(Garen.camp))
结果:
43227208
43227208
而类的属性是绑定到所有的对象
print(id(r1.attack))
print(id(Riven.attack))
结果:
34910088
36486272
r1.attack就是在执行Riven.attack的功能,python的class机制会将Riven的函数属性attack绑定给r1,r1相当于拿到了一个指针,指向Riven类的attack功能
除此之外r1.attack()会将r1传给attack的第一个参数
对象(实例)名称空间
创建一个对象(实例),就会创建一个对象(实例)的名称空间,存放着对象的名字,称为对象(实例)的属性
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
2 基于面向对象设计程序
要严格按照下面的流程:
1 面向对象程序设计 OOD
- 找对象-->找类(归纳对象共同的特征和技能,每个对象独有的特征)
2面向对象程序编程OOP
- 先定义类--实例化对象
要针对当前的额应用场景
对象:学校--->归类
共有的特征:商标
共有的技能:招生
独有的特征:地址,老师们 、课程
```python
class School:
tag
对象:老师
共有的特征:无
共有的技能:授课
独有的特征:名字,level,课程
对象:学生
共有的特征:
共有的技能:search_score,handin
独有的特征:name,id,
# 对象:学校--->归类
# 共有的特征:商标
# 共有的技能:招生
# 独有的特征:地址,老师们 、课程
class School:
tag = 'xuexiao'
def __init__(self,addr):
sell.addr = addr
self.teach_list = [] # 直接在这里新建一个空的列表
self.course=[] #新建一个课程的列表
def zhaosheng(self):
pass
# 对象:老师
# 共有的特征:无
# 共有的技能:授课
# 独有的特征:名字,level,课程
class Teacher:
def __init__(self,name,level,course):
self.name = name
self.level = level
self.course = course
def teach(self):
pass
# 对象:学生
# 共有的特征:
# 共有的技能:search_score,handin 课程
# 独有的特征:name,id,
class Student:
def __init__(self,ID,name,sex):
self.id = ID
self.name = name
self.sex = sex
self.course_list= []
def search(self):
pass
def handin(self):
pass
# 定义一个课程的类
class Course:
def __init__(self,name,price,period):
self.name = name
self.price = price
self.period = period
s1 = Student('1123','aaa','female')
#
# s1.course_list.append('python')
# s1.course_list.append('linux')
# print(s1.course_list)
python_obj = Course("python",10000,'5m')
linux_obj = Course('python',2200,'2m')
s1.course_list.append(python_obj) # 直接添加的是Course的类
s1.course_list.append(linux_obj)
print(s1.course_list[0].name) # s1.course_list[0]取到的是Python_obj
print('''student name is :%s
student price is :%s
student period is :%s'''
%(s1.course_list[0].name,s1.course_list[0].price,s1.course_list[0].period))