进击のpython
面向对象
唉,脑阔疼,昨天写的,忘记报错了,还要重新写!!!!!!!
不逼逼叨了
如果此时此刻的你学过面向对象的编程
那我极力不建议你看这篇博文
因为我不想跟杠精battle
熟悉我的博文的都知道
每次要学新的东西的时候
都是从需求开始引入
那么需求来了!
我想做个游戏!
怎么玩呢?
我要有很多的狗,我还要有很多的人
狗可以咬人,人可以打狗
好,设计吧!
抛开很多不谈,我们现在应该先整一只狗出来
狗有什么属性呢?
d_name 名字
d_kind 种类
d_blod 血量
d_atta 攻击
好,确定了属性就整个狗!
dog = {"d_name": "ponny",
"d_kind": "erha",
"d_blod": 100,
"d_atta": 20, }
这是一只狗对吧
那我现在想要两只狗
怎么写?
dog = {"d_name": "ponny",
"d_kind": "erha",
"d_blod": 100,
"d_atta": 20, }
dog1 = {"d_name": "helly",
"d_kind": "laswer",
"d_blod": 100,
"d_atta": 10, }
写完我们发现
这两个狗的重复代码太多了(键)
所以使得代码不够简洁!
需要有一种方法直接把重复的放起来,只修改想改的地方
而且我这只是两只狗
我可是要很多的狗!!!
那我们要怎么做呢?????
这个时候,是不是就想到了
我们可以用函数来做!(如果前面的函数没看懂,别往下看!)
函数怎么做呢?
def dog(name, kind):
data = {"d_name": name,
"d_kind": kind,
"d_blod": 100,
"d_atta": 20, }
return data
这是不是就是函数的传参啊!没问题吧!
那狗整出来了,人是不是也是同理的啊
def person(name, sex):
data = {"p_name": name,
"p_sex": sex,
"p_blod": 100,
"p_atta": 20, }
return data
那我又有问题了!
狗都一样???不是吧!不同品类的狗有不同的亚子
攻击力也就不一样是吧
那我们就可以优化一下代码!
dog_count = {"erha": 20,
"laswer": 10}
def dog(name, kind):
if kind in dog_count:
data = {"d_name": name,
"d_kind": kind,
"d_blod": 100,
"d_atta": dog_count[kind], }
else:
print("品种不明!")
return None
return data
有问题吗?(有问题先在这停一下,慢慢看这个代码,看懂了再继续)
我寻思着,怎么?狗不一样,人就一样了????
那就继续优化呗!
def person(name, sex):
data = {"p_name": name,
"p_sex": sex,
"p_blod": 100,
"p_atta": 20, }
if sex == "man":
data["p_atta"] = 30
return data
上面两个方法相当于造了两个模子
游戏开始,你得生成一个人和狗吧,怎么生成呢?
函数的调用啊!(你看,你要是不会函数,你能看懂????)
dog1 = dog("ponny", "erha")
dog2 = dog("helly", "laswer")
person1 = person("zhangsan", "man")
我这代码怎么个意思?
是不是整出两只狗,再带上一个人??
有对象了,是不是要开始写狗咬人和人打狗了?
还是用函数的方法来写(咋的,你就打一下啊!)
def bite(dog_obj, person_obj):
person_obj["p_blod"] -= dog_obj["d_atta"]
print("疯狗[%s]咬了[%s],掉血[%s]..." % (dog_obj["d_name"], person_obj['p_name'], dog_obj["d_atta"]))
def beat(person_obj, dog_obj):
dog_obj["d_blod"] -= person_obj['p_atta']
print("[%s] 打了 疯狗[%s],狗掉血[%s]..." % (person_obj["p_name"], dog_obj["d_name"], person_obj["p_atta"]))
(顺便来了一个格式化输出)
好了,都写完了吧!开始玩吧(判断血量<0死亡这种东西先不整┗|`O′|┛ 嗷~~)
dog_count = {"erha": 20,
"laswer": 10}
def dog(name, kind):
if kind in dog_count:
data = {"d_name": name,
"d_kind": kind,
"d_blod": 100,
"d_atta": dog_count[kind], }
else:
print("品种不明!")
return None
return data
def person(name, sex):
data = {"p_name": name,
"p_sex": sex,
"p_blod": 100,
"p_atta": 20, }
if sex == "man":
data["p_atta"] = 30
return data
def bite(dog_obj, person_obj):
person_obj["p_blod"] -= dog_obj["d_atta"]
print("疯狗[%s]咬了[%s],掉血[%s]..." % (dog_obj["d_name"], person_obj['p_name'], dog_obj["d_atta"]))
def beat(person_obj, dog_obj):
dog_obj["d_blod"] -= person_obj['p_atta']
print("[%s] 打了 疯狗[%s],狗掉血[%s]..." % (person_obj["p_name"], dog_obj["d_name"], person_obj["p_atta"]))
dog1 = dog("ponny", "erha")
dog2 = dog("helly", "laswer")
person1 = person("zhangsan", "man")
bite(dog2, person1)
beat(person1, dog1)
功能简直完美!!
但是你玩着玩着,你就发现
咬人这个动作(函数)
应该是狗对人的吧(当然有些人也不一定是人)
那我要是把人放进去呢?
bite(person1, dog1)
你把人传给了只有狗能用的方法
你发现完蛋了!后面全错了!
怎么解决呢?
可能会有人说,那我加个判断就好了
对!
加判断是一种方法!(自己做啊,能做出来的!)
但是我们进阶的想想!
你看┗|`O′|┛ 嗷~~
这个咬人 (bite)是不是狗(dog)的动作
而且,只能是狗(dog)的!
所以 ,我们是不是可以这样!
把咬人(bite)的方法放进狗(dog)里
这样就变成了,你必须调用狗(dog)
才能调用咬人(bite)这个动作(函数)
def dog(name, kind):
if kind in dog_count:
data = {"d_name": name,
"d_kind": kind,
"d_blod": 100,
"d_atta": dog_count[kind], }
else:
print("品种不明!")
def bite(dog_obj, person_obj):
person_obj["p_blod"] -= dog_obj["d_atta"]
print("疯狗[%s]咬了[%s],掉血[%s]..." % (dog_obj["d_name"], person_obj['p_name'], dog_obj["d_atta"]))
return data
这样虽然有点意思,但是经不起深究
首先,我必须要调用才能执行对吧!
那我就还应该加一个bite()
def dog(name, kind):
if kind in dog_count:
data = {"d_name": name,
"d_kind": kind,
"d_blod": 100,
"d_atta": dog_count[kind], }
else:
print("品种不明!")
def bite(dog_obj, person_obj):
person_obj["p_blod"] -= dog_obj["d_atta"]
print("疯狗[%s]咬了[%s],掉血[%s]..." % (dog_obj["d_name"], person_obj['p_name'], dog_obj["d_atta"]))
bite() # 在这呢!!!
return data
那我加完之后问题又来了!
你违背了我刚开始创建dog()这个函数的初心啊
我本意是调用这个函数,生成一个狗
你现在是调用了,就让他去咬人!
那我想生成个不咬人的都不行!
所以,这么写是有问题的
所以我们不应该把bite()直接放进去
应该想用bite()的时候再用
def dog(name, kind):
if kind in dog_count:
data = {"d_name": name,
"d_kind": kind,
"d_blod": 100,
"d_atta": dog_count[kind], }
else:
print("品种不明!")
def bite(dog_obj, person_obj):
person_obj["p_blod"] -= dog_obj["d_atta"]
print("疯狗[%s]咬了[%s],掉血[%s]..." % (dog_obj["d_name"], person_obj['p_name'], dog_obj["d_atta"]))
data["bite"] = bite ### 看这里!!!! 为了外部可以调用!!!!
return data
dog1 = dog("ponny", "erha")
print(dog1["bite"])
# <function dog.<locals>.bite at 0x051A7930>
看,是不是返回了一个函数那我要是想调用这个函数,就加个括号就行了呗
然后我们进行代码终极优化!
dog_count = {"erha": 20,
"laswer": 10}
def dog(name, kind):
if kind in dog_count:
data = {"d_name": name,
"d_kind": kind,
"d_blod": 100,
"d_atta": dog_count[kind], }
else:
print("品种不明!")
def bite(person_obj):
person_obj["p_blod"] -= data["d_atta"]
print("疯狗[%s]咬了[%s],掉血[%s]..." % (data["d_name"], person_obj['p_name'], data["d_atta"]))
data["bite"] = bite
return data
def person(name, sex):
data = {"p_name": name,
"p_sex": sex,
"p_blod": 100,
"p_atta": 20, }
if sex == "man":
data["p_atta"] = 30
def beat(dog_obj):
dog_obj["d_blod"] -= data['p_atta']
print("[%s] 打了 疯狗[%s],狗掉血[%s]..." % (data["p_name"], dog_obj["d_name"], data["p_atta"]))
data["beat"] = beat
return data
dog1 = dog("ponny", "erha")
dog2 = dog("helly", "laswer")
person1 = person("zhangsan", "man")
dog1["bite"](person1)
person1["beat"](dog2)
完美实现需求对吧!!
而当你对狗传进去狗的时候,就会报错(自己试试!)
逼逼了这么多,有什么用呢?
跟面向对象有什么关系?
其实你上面写的代码就是面向对象的编程!
你在设计角色时,为了让一个角色可以变成多个实体对象
你设计了一个基础模板,只要传入不同参数,就会产生不同的角色
这代表你已经开始切换成上帝视角看事情 ,上帝视角就是面向对象编程的视角
上帝要造世界万物,他肯定不是一个一个的造出来
他肯定是设计出一个个的物种的模板,然后通过模子批量批一个个的实体造出来
造出来的实体各有特色,属性、功能都不尽相同,有的人的贪婪、有的人好色、有的人懦弱,有的人勇猛
这些人之间会发生什么关系 ,谁和谁交媾、谁和谁打仗,上帝懒的管,上帝只控制大局