一、面向过程 VS 面向对象
面向过程:
面向过程的程序设计的核心是过程(流水线式思维)
优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。
缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。
面向对象:
面向对象的程序设计的核心是对象(上帝式思维)
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。
二、类和对象
'''
class 类名:
'类的文档字符串'
类体
'''
#我们创建一个类
class Data:
pass
一:我们定义的类的属性到底存到哪里了?有两种方式查看 dir(类名):查出的是一个名字列表 类名.__dict__:查出的是一个字典,key为属性名,value为属性值 二:特殊的类属性 类名.__name__# 类的名字(字符串) 类名.__doc__# 类的文档字符串 类名.__base__# 类的第一个父类(在讲继承时会讲) 类名.__bases__# 类所有父类构成的元组(在讲继承时会讲) 类名.__dict__# 类的字典属性 类名.__module__# 类定义所在的模块 类名.__class__# 实例对应的类(仅新式类中)
对象 = 类名()
过程:
类名() 首先 会创造出一个对象,创建了一个self变量
调用init方法,类名括号里的参数会被这里接收
执行init方法
返回self
对象能做的事:
查看属性
调用方法
__dict__ 对于对象的增删改查操作都可以通过字典的语法进行
类名能做的事:
实例化
调用方法 : 只不过要自己传递self参数
调用类中的属性,也就是调用静态属性
__dict__ 对于类中的名字只能看 不能操作
栗子:
class Person: # 类名
country = 'China' # 创造了一个只要是这个类就一定有的属性
# 类属性 静态属性
def __init__(self,*args): # 初始化方法,self是对象,是一个必须传的参数
# self就是一个可以存储很多属性的大字典
self.name = args[0] # 往字典里添加属性的方式发生了一些变化
self.hp = args[1]
self.aggr = args[2]
self.sex = args[3]
def walk(self,n): # 方法,一般情况下必须传self参数,且必须写在第一个
# 后面还可以传其他参数,是自由的
print('%s走走走,走了%s步'%(self.name,n))
print(Person.country) # 类名 可以查看类中的属性,不需要实例化就可以查看
alex = Person('狗剩儿',100,1,'不详') # 类名还可以实例化对象,alex对象 # 实例化
print(alex.__dict__) # 查看所有属性
print(alex.name) # 查看属性值
print(alex.hp) # 查看属性值
alex.walk(5) # Person.walk(alex,5) # 调用方法 类名.方法名(对象名)
栗子:人狗大战
def Dog(name,blood,aggr,kind):
dog = {
'name': name,
'blood': blood, # 血量
'aggr': aggr, # 攻击力
'kind': kind,
}
def bite(person):
person['blood'] -= dog['aggr']
print('%s被咬了,掉了%s的血' % (person['name'], dog['aggr']))
dog['bite'] = bite
return dog
def Person(name,blood,aggr,sex):
person = {
'name' : name,
'blood': blood, # 血量
'aggr': aggr, # 攻击力
'sex':sex,
}
def attack(dog):
dog['blood'] -= person['aggr']
print('%s被打了,掉了%s的血' % (dog['name'], person['aggr']))
person['attack'] = attack
return person
# 代码精简了 方便增加人物 方便修改 人物更加规范 —— 人模子
jin = Dog('金老板',1000,100,'teddy')
alex = Person('狗剩儿',100,1,'不详')
# nezha = Person('哪吒',200,2,'不详')
print(jin)
jin['bite'](alex)
alex['attack'](jin)
Dog函数和Person函数 都是定义了一类事物
直到调用了函数,赋值了之后才真的有了一个实实在在的人或狗
面向对象编程:
所谓模子 就是 类 抽象的 我能知道有什么属性 有什么技能 但不能知道属性具体的值
jin alex nezha 就是对象 有具体的值,属性和技能都是根据类规范的
加强版人狗大战:
定义一个人类:
class Person: # 定义一个人类
role = 'person' 人的角色属性都是人
def __init__(self, name, aggressivity, life_value, money):
self.name = name 每一个角色都有自己的昵称;
self.aggressivity = aggressivity 每一个角色都有自己的攻击力;
self.life_value = life_value 每一个角色都有自己的生命值;
self.money = money
def attack(self,dog):
人可以攻击狗,这里的狗也是一个对象。
人攻击狗,那么狗的生命值就会根据人的攻击力而下降
dog.life_value -= self.aggressivity
定义一个狗类:
class Dog: # 定义一个狗类
role = 'dog' 狗的角色属性都是狗
def __init__(self, name, breed, aggressivity, life_value):
self.name = name 每一只狗都有自己的昵称;
self.breed = breed 每一只狗都有自己的品种;
self.aggressivity = aggressivity 每一只狗都有自己的攻击力;
self.life_value = life_value 每一只狗都有自己的生命值;
def bite(self,people):
狗可以咬人,这里的狗也是一个对象。
狗咬人,那么人的生命值就会根据狗的攻击力而下降
people.life_value -= self.aggressivity
又创建一个新的兵器类:
class Weapon:
def __init__(self,name, price, aggrev, life_value):
self.name = name
self.price = price
self.aggrev = aggrev
self.life_value = life_value
def update(self, obj): obj就是要带这个装备的人
obj.money -= self.price 用这个武器的人花钱买所以对应的钱要减少
obj.aggressivity += self.aggrev 带上这个装备可以让人增加攻击
obj.life_value += self.life_value 带上这个装备可以让人增加生命值
def prick(self, obj): 这是该装备的主动技能,扎死对方
obj.life_value -= 500 假设攻击力是500
测试交互 :
lance = Weapon('长矛',200,6,100)
egg = Person('egon',10,1000,600) 创造了一个实实在在的人egg
ha2 = Dog('二愣子','哈士奇',10,1000) 创造了一只实实在在的狗ha2
egg独自力战"二愣子"深感吃力,决定穷毕生积蓄买一把武器
if egg.money > lance.price: 如果egg的钱比装备的价格多,可以买一把长矛
lance.update(egg) egg花钱买了一个长矛防身,且自身属性得到了提高
egg.weapon = lance egg装备上了长矛
print(egg.money,egg.life_value,egg.aggressivity)
print(ha2.life_value)
egg.attack(ha2) egg打了ha2一下
print(ha2.life_value)
egg.weapon.prick(ha2) 发动武器技能
print(ha2.life_value) ha2不敌狡猾的人类用武器取胜,血槽空了一半
类有两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量
- 动态属性就是定义在类中的方法