1.面向对象引入
先来创建一个小游戏:人狗大战
# 定义一个狗 def Gog(name,blood,aggr,kind): dog = { 'name':name, 'blood':blood, 'aggr':aggr, 'kind':kind } return dog # 定义一个人 def Person(name,blood,aggr,kind): person ={ 'name':name, 'blood':blood, 'aggr':aggr, 'kind':kind } return person # 定义一个人的技能 打 def attack(person,dog): dog['blood'] -= person['aggr'] print('{}被打了,掉了{}的血'.format(dog['name'],person['aggr'])) # 定义一个狗的技能 咬 def bite(dog,person): person['blood'] -= dog['aggr'] print('{}被咬了,掉了{}的血'.format(person['name'],dog['aggr'])) yellow = Gog('dahuang',1000,100,'jinmao') alex = Person('alex',800,50,'战士') bite(yellow,alex) # "alex被咬了,掉了100的血" bite(alex,yellow) # "dahuang被咬了,掉了50的血" 这里就出现了一些问题,狗咬狗
以上方法会出现 “人咬狗”的错误。衍生了人狗大战第二版
# 定义一个狗 def Gog(name,blood,aggr,kind): dog = { 'name':name, 'blood':blood, 'aggr':aggr, 'kind':kind } def bite(person): person['blood'] -= dog['aggr'] print('{}被咬了,掉了{}的血'.format(person['name'], dog['aggr'])) dog['bite'] = bite # 将狗的技能作为一个字典参数加进来 return dog # 定义一个人 def Person(name,blood,aggr,kind): person ={ 'name':name, 'blood':blood, 'aggr':aggr, 'kind':kind } def attack(dog): dog['blood'] -= person['aggr'] print('{}被打了,掉了{}的血'.format(dog['name'], person['aggr'])) person['attack'] = attack # 将人的打技能作为字典参数传进来 return person yellow = Gog('dahuang',1000,100,'jinmao') alex = Person('alex',800,50,'战士') print(yellow) # 在狗,大黄内自带一个函数,需要传参:被咬的人 # {'name': 'dahuang', ...'bite': <function Gog.<locals>.bite at 0x0000027FAED2ABF8>} yellow['bite'](alex) # 给大黄的咬的技能函数加入一个参数人,一样可以得到结果 # alex被咬了,掉了100的血
2.面向对象编程理解
- 所谓模子 就是类 抽象的,例如上面的函数人。例如人类
- 但是根据 模子刻出来的就是对象,例如 根据狗刻出来的yellow(大黄)。人类中的科比,姚明为对象
- 先有类再有对象
3.面向对象初识
# 自定义类 class Person: # 类名 country = 'China' # 创建一个类属性(静态属性), def __init__(self,*args): # self 类似于一个可以存储很多属性的字典 (初始化方法,self是必须传参数) # print(self.__dict__) # 此处可看到self是一个空字典 self.name = args[0] # name,hp,aggr,sex类似于在字典里放置属性 self.hp = args[1] self.aggr = args[2] self.sex = args[3] print(self.__dict__) # 此处可看到字典多了key,value # print(id(self)) # 内存地址与 'alex' 内存地址一样 def work(self,n): # self 是一个必要的任意参数,一般叫self。 (函数写在类中叫方法,一般必须传第一个self参数,后面其他参数) print('{}走走走,走了{}步'.format(self.name,n)) alex = Person('二狗子',100,50,'男') #alex对象 实例化。 执行类 + 括号就是在调用__init__(self)方法 print(alex.__dict__) # 此处 # print(id(alex)) Person.work(alex,5) # 调用方法 类名.方法名(对象名) alex.work(10) # 等价于 Person.work(alex) print(Person.country) alex.__dict__['name'] = '中华田园犬' print(alex.name) alex.name = '土狗' print(alex.__dict__['name']) # alex.name == alex.__dict__['name'] 增删 # 类的属性是不可以进行修改的 # 对象可以做的事: # 1.查看属性(alex.name), # 2.调用方法(alex.work()) # 3.对于对象的增删改查可以通过__dict__方法进行或者 对象.属性 # 类名可以做的事: # 1.实例化对象 # 2.调用方法,需要自己传递self参数 # 3.调用类属性,静态属性 # 4.__dict__对于类中的属性等只能看不能操作 #################### {'name': '二狗子', 'hp': 100, 'aggr': 50, 'sex': '男'} {'name': '二狗子', 'hp': 100, 'aggr': 50, 'sex': '男'} 二狗子走走走,走了5步 二狗子走走走,走了10步 China 中华田园犬 土狗
4.面向对象练习
4.1 人狗大战面向对象版
class Dog: def __init__(self,name,blood,aggr,kind): self.na = name self.hp = blood self.gong = aggr self.kin = kind def bite(self,person): # 狗咬人,人掉血 person.hp -= self.gong if person.hp <= 0: print('{}咬了{},{}被咬死了'.format(self.na,person.na,person.na)) else: print('{}咬了{},掉了{}血'.format(self.na,person.na,self.gong)) class Person: def __init__(self,name,blood,aggr,sex): self.na = name self.hp = blood self.gong = aggr self.se = sex def attrck(self,ddog): # 人打狗,狗掉血 ddog.hp -= self.gong if ddog.hp <= 0: print('{}打了{},{}被打死了'.format(self.na,ddog.na,ddog.na)) else: print('{}打了{},掉了{}血'.format(self.na,ddog.na,self.gong)) dijia = Person('奥特曼',500,50,'man') yellow_dog = Dog('大黄',300,20,'teddy') yellow_dog.bite(dijia) dijia.attrck(yellow_dog)
""" 大黄咬了奥特曼,掉了20血 奥特曼打了大黄,掉了50血
4.2 圆的面积和周长
class circle: def __init__(self,banjin): self.bj = banjin def zhouchang(self): return self.bj * 2 * 3.14 def mianji(self): return self.bj ** 2 * 3.14 ab = circle(2) print(ab.zhouchang()) print(ab.mianji())
小结:
- 当有几个函数需要反复传入相同参数的时候,可以考虑使用面向对象
- 非常明显的处理一类事物,这些食物具有相同的属性和功能
- 参数都是对象的属性