人狗大战的游戏

你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢?

你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色

def Person(name,sex,hp,ad):
self = {'name':name,'sex':sex,'hp':hp,'ad':ad}
return dict def Dog(name,kind,hp,ad):
self = {'name': name, 'sex': kind, 'hp': hp, 'ad': ad}
return dict

上面两个方法相当于造了两个模子,游戏里的每个人和每条狗都拥有相同里的属性。游戏开始,你根据一个人或一只狗传入的具体信息来塑造一个具体的人或者狗,怎么生成呢?

alex = Person('a_sb','不祥',50,50)
chen = Dog('旺财','teddy',50,40)
boss_jin = Person('金老板','男',60,60)

两个角色对象生成了,狗和人还有不同的功能呀,狗会咬人,人会打狗,对不对? 怎么实现呢,。。想到了, 可以每个功能再写一个函数,想执行哪个功能,直接 调用 就可以了,对不?

def attack(dog):
print('%s攻击%s' % (self['name'], dog['name'])) def bite(person):
print('%s咬%s' % (self['name'], person['name'])) attack(chen)
bite(alex)

上面的功能实现的简直是完美!

但是仔细玩耍一会,你就不小心干了下面这件事

boss_jin = Person('金老板','男',60,60)
bite(boss_jin) #把人的对象传给了狗的方法

事实 上,从你写的代码上来看,这并没出错。很显然,人是不能调用狗的功能的,但在你的程序例没有做限制,如何在代码级别实现这个限制呢?

ef Person(name,sex,hp,ad):
self = {'name':name,'sex':sex,'hp':hp,'ad':ad}
def attack(dog):
print('%s攻击%s' % (self['name'], dog['name']))
dog['hp'] -= self['ad']
self['attack'] = attack
return self def Dog(name,kind,hp,ad):
self = {'name': name, 'sex': kind, 'hp': hp, 'ad': ad}
def bite(person):
print('%s咬%s' % (self['name'], person['name']))
person['hp'] -= self['ad']
self['bite'] = bite
return self alex = Person('a_sb','不祥',50,50)
chen = Dog('旺财','teddy',50,40)
boss_jin = Person('金老板','男',60,60)
alex['attack'](chen)
boss_jin['attack'](chen)
chen['bite'](alex)

面向对象编程

类和对象

1.类的概念:具有相同属性和技能的一类事物(抽象)。

2.对象的概念:对一个类的具体描述(具体)。

比如人类就是一个抽象的概念,有具体哪一个人有什么特征就是对象。

使用面向对象的好处

1.是的代码之间的角色关系更加明确。

2.增强了代码的可扩展性

3.规范了对象的属性和方法技能。

面向对象的特点:结局的不确定性。

面向对象的语法

class Person:# 定义一个类
静态变量 = 123 # 静态属性(变量),可以引用多个
def f1(self): #动态属性(变量,方法),默认带一个参数self
。 print(666)

类的作用:

1.属性引用

 1)引用静态属性的方式

类名.__dict__[''静态属性],可以查看静态属性,但是不能修改。

class Person:# 定义一个类
静态属性 = 123
def f1(self):
print(666)
print(Person.__dict__['静态属性'])
Person.__dict__['静态属性'] = 456
print(Person.__dict__['静态属性']) # 报错,只能引用不能修改

类名.静态属性  可以直接访问,可以修改。

class Person:# 定义一个类
静态属性 = 123
def f1(self):
print(666)
print(Person.静态属性)
Person.静态属性 = 456 #改变静态变量
print(Person.静态属性)

删除静态属性的方法:del 类名.静态属性

class Person:# 定义一个类
静态属性 = 123
def f1(self):
print(666)
del Person.静态属性
print(Person.__dict__['静态属性'])

2)引用动态属性

类名.方法名 查看这个方法的内存地址。

类名.方法名(实参)调用了这个方法,必须传一个实参,这个实参传给了self。
class Person:
role = 'person'
def f1(self):
print(666)
Person.f1(1) #666
print(Person.f1) #<function Person.f1 at 0x00000054A5E83730>

3)创造一个对象——实例化

产生一个实例(对象)的过程叫实例化

语法:对象=类名() 如:alex = Person()

实例化过程:

1.创造一个实例,将会作为一个实际参数。

2.自动触发一个__init__的方法,并把实例以参数的形式传递给__init__方法。

3.执行完__init__方法之后,会将self自动返回给alex。

class Person:
def __init__(self,name,sex,hp,ad):
self.name = name #self 里存储的内容叫对象属性
self.sex = sex
self.hp = hp
self.ad = ad alex = Person('a_sb','男',1,5)
alex.__dict__['name'] = 'alex' # 修改name
print(alex.name)#查看属性:对象名.属性名
备注:__init__方法:初始化方法,给一个对象添加一些基础属性的方法,一般情况下是针对self的赋值

对象

1.在类的内部,self是本类的一个对象。

2.在类的外部,每一个对象都对应着一个名字,这个对象指向一个对象的内存空间。

3.属性的调用:

对象名.属性名

对象名__dict__['属性名']

4.方法的调用:

类名.方法名(对象名)#方法中的self参数就指向这个对象。

对象名.方法名()  #这样写相当于方法中的self参数就指向这个对象。


class Person:
role = 'person'
def __init__(self,name,sex,hp,ad):
self.name = name #self 里存储的内容叫对象属性
self.sex = sex
self.hp = hp
self.ad = ad
def attack(self):
print('%s发起了一次攻击' % self.name) alex = Person('a_sb','男',1,5)
# Person.attack(alex)
alex.attack()

对象之间的交互

class Person: # 定义一个人类
role = 'person'# 人的角色属性都是人
def __init__(self,name,sex,hp,ad): # 定义一个对象
self.name = name #每一个角色都有自己的属性
self.sex = sex
self.hp = hp
self.ad = ad
def attack(self,dog): #给人类定义一个攻击的方法
dog.hp -= self.ad
print('%s攻击了%s,%s掉了%s点血' % (self.name,dog.name,dog.name,self.ad)) class Dog: #定义一个狗类
role = 'dog' #狗的角色属性都狗
def __init__(self,name,kind,hp,ad):
self.name = name # 狗的属性
self.kind = kind
self.hp = hp
self.ad = ad
def bite(self,person): # 给狗类定义一个咬方法
person.hp -= self.ad
print('%s咬了%s一口,%s掉了%s点血' % (self.name,person.name,person.name,self.ad)) alex = Person('alex','男',50,30) # 实例一个人
ha2 = Dog('笨笨','二哈',80,50) # 实例一个狗
alex.attack(ha2)
print('%s还剩%s点血' % (ha2.name,ha2.hp))
ha2.bite(alex)
print('%s还剩%s点血' % (alex.name,alex.hp))

 类命名空间与对象、实例的命名空间

对象的内存空间里只存储对象的属性,而不存储方法和静态属性。

类的内存空间里存储方法和静态属性,为了节省内存,让多个对象去共享类中的资源。

代码从上至下执行,在全局命名空间里创建一个类(Person)的名称空间,用来存储role、__init__、attack这些属性,调用类名时实例化一个对象,创建一个名称空间,self指向这个空间地址,对象的参数添加到这个空间,这个空间的内存地址返回给对象alex,名称空间内有一个类对象指针 指向类名,通过类对象指针找到类名称空间。

# 类的命名空间:
class Person:
role = 'person' # 静态属性
def __init__(self,name,sex,hp,ad):
self.name = name # 对象属性 属性
self.sex = sex
self.hp = hp
self.ad = ad
def attack(self):
self.hobby = 'girl'
print('%s发起了一次攻击'%self.name) alex = Person('a_sb','不详',1,5)
alex.attack() # Person.attack(alex)
alex ---> person # alex如何找到person
person实例化了alex alex.name # alex指向自己的内存空间,在自己的内存空间里找到name
alex.attack # alex先找到自己的内存空间,再找到类对象指针,根据类对象指针找到类,再通过类找到attack

对象的属性是独有的,静态属性和方法是共享的,对象使用名字先找自己内存空间里的,再找类的内存 空间里的。

class Person:
role = 'person' # 静态属性
def __init__(self,name,sex,hp,ad):
self.name = name # 对象属性 属性
self.sex = sex
self.hp = hp
self.ad = ad
self.attack = 'hahaha'
def attack(self):
self.hobby = 'girl'
print('%s发起了一次攻击'%self.name) alex = Person('a_sb','不详',1,5)
alex.attack() # 报错

对象在接收一个属性时只能放在自己的内存空间里。

class Person:
role = 'person' # 静态属性
def __init__(self,name,sex,hp,ad):
self.name = name # 对象属性 属性
self.sex = sex
self.hp = hp
self.ad = ad
self.attack = 'hahaha'
def attack(self):
self.hobby = 'girl'
print('%s发起了一次攻击'%self.name) alex = Person('a_sb','不详',1,5)
boss_jin = Person('金老板','男',10,20)
alex.role = 'dog'
print(alex.role) #dog
print(boss_jin.role) #person
class Person:
money = [0] #列表在内存中开辟一个空间存储每个元素的地址,通过地址找到对应的值
def __init__(self,name):
self.name = name
def work(self):
print(self.name,'工作,赚了1000块钱')
self.money[0] += 1000 father = Person('father')
mother = Person('mother')
mother.work()
father.work()
print(Person.money) # 2000 没有改变类中的关系

静态变量属性的修改:类名.静态变量名

面向对象的实例

计算圆的周长和面积:半径1,2,5,7,9

from math import pi
class Circle:
def __init__(self,r):
self.r = r
def cal_area(self):
return pi*self.r**2
def cal_perimeter(self):
return pi*self.r*2
for i in range(1,10,2):
c1 = Circle(i)
print(c1.cal_area())
print(c1.cal_perimeter())

 面向对象的组合用法:

组合概念:一个类对象作为另一个类对象的属性,表示一种什么有什么的关系。

为什么用组合:独立的对象不能发挥它的作用,必须依赖一个对象。

人狗大战升级版之组合

class Person:
def __init__(self,name,sex,hp,ad):
self.name = name
self.sex = sex
self.hp = hp
self.ad = ad
self.money = 0
def attack(self,dog):
dog.hp -= self.ad
print('%s攻击了%s,%s掉了%s点血'% (self.name,dog.name,dog.name,self.ad))
def pay(self):
money = int(input('请输入您要充值的金额:'))
self.money += money
print('您的余额是%s' % self.money)
def wear(self,weapon): #
if self.money >= weapon.price:
self.weapon = weapon # 武器类对象作为人类对象的一个属性
self.money -= weapon.price
print('购买成功,您已经顺利装备了%s' % weapon.name)
else:
print('余额不足,请充值。')
def attack_with_weapon(self,dog):
if 'weapon' in self.__dict__:
self.weapon.skill(dog)
else:
print('请先装备武器') class Dog:
def __init__(self,name,kind,hp,ad):
self.name = name
self.kind = kind
self.hp = hp
self.ad = ad
def bite(self,person):
person.hp -= self.ad
print('%s咬了%s,%s掉了%s点血' % (self.name, person.name, person.name, self.ad)) class Weapon: #定义一个武器类
def __init__(self,name,price,ad,level): #武器类具有名字、价格、攻击力、品级的属性
self.name = name
self.price = price
self.ad = ad
self.level = level
def skill(self,dog): # 武器的方法
dog.hp -= self.ad
print('%s受到了%s的伤害,%s掉了%s点血' % (dog.name,self.name,dog.hp,self.ad)) alex = Person('sb','man',20,10)
boss_jin = Person('金老板','男',50,50)
teddy = Dog('笨笨','teddy',150,100)
nife = Weapon('刀',500,100,1) # alex.pay()
# alex.wear(nife) # 装备了刀
# print(alex.__dict__) #{'name': 'sb', 'ad': 10, 'weapon': <__main__.Weapon object at 0x0000006F587462B0>, 'hp': 20, 'sex': 'man', 'money': 0}
# print(alex.weapon) # alex.weapon = nife
# print(nife) #<__main__.Weapon object at 0x0000006F587462B0>
# alex.weapon.skill(teddy) lst = ['攻击','充值','装备武器','使用武器攻击']
while True:
for index,value in enumerate(lst,1):
print(index,value)
num = int(input('请选择操作序号>>>'))
if num == 1:
alex.attack(teddy)
elif num == 2:
alex.pay()
elif num == 3:
print('装备前余额%s' % alex.money)
alex.wear(nife)
print('装备后余额%s' % alex.money)
elif num == 4:
alex.attack_with_weapon(teddy)
else:
print('无效的序号')

组合实例:计算圆环的面积

from math import pi
class Circle:
def __init__(self,r):
self.r = r
def cal_area(self):
return pi*self.r**2
def cal_perimeter(self):
return pi*self.r*2
class Ring:
def __init__(self,r1,r2): #r1=5,r2=2
self.r1 = Circle(r1) #圆的对象,实例化大圆
self.r2 = Circle(r2) #圆的对象,实例化小圆
def ring_area(self):
return self.r1.cal_area() - self.r2.cal_area()
def ring_perimeter(self):
return self.r1.cal_perimeter()+self.r2.cal_perimeter() ring = Ring(5,2)
print(ring.ring_area())
												

初识面向对象(Day17-Day18)的更多相关文章

  1. 第五章 JavaScript对象及初识面向对象

    第五章   JavaScript对象及初识面向对象 一.对象 在JavaScript中,所有事物都是对象,如字符串.数值.数组.函数等. 在JavaScript对象分为内置对象和自定义对象,要处理一些 ...

  2. python - 初识面向对象

    1.初识面向对象       面向过程:一切以事务的发展流程为中心           优点:负责的问题流程化,编写相对简单         缺点:可扩展性差,只能解决一个问题,改造也会很困难,牵一发 ...

  3. python之路--初识面向对象

    一 . 初识面向对象 面向过程: 一切以事务的发展流程为中心. 面向对象: 一切以对象为中心. 一切皆为对象. 具体的某一个事务就是对象 打比方: 大象进冰箱 步骤: 第一步, 开门, 第二步, 装大 ...

  4. python 全栈开发,Day19(组合,组合实例,初识面向对象小结,初识继承)

    一.组合 表示的一种什么有什么的关系 先来说一下,__init__的作用 class Dog: def __init__(self, name, kind, hp, ad): self.name = ...

  5. Day7 初识面向对象,面向对象之继承、多态和封装

    一.面向对象引言 一.面向对象的程序设计的由来 详述见:http://www.cnblogs.com/linhaifeng/articles/6428835.html 二.面向对象引子 写一个简单程序 ...

  6. Java基础-初识面向对象编程(Object-Oriented-Programming)

    Java基础-初识面向对象编程(Object-Oriented-Programming) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java是一门面向对象的程序设计语言.那么什 ...

  7. python学习之老男孩python全栈第九期_day022知识点总结——初识面向对象

    一. 面向对象的引入# 人狗大战 def person(name,HP,aggr,sex): person = { 'name':name, # 昵称 'HP':HP, # 生命值 'aggr':ag ...

  8. 巨蟒python全栈开发-第16天 核能来袭-初识面向对象

    一.今日内容总览(上帝视角,大象自己进冰箱,控制时机) #转换思想(从面向过程到面向对象) 1.初识面向对象 面向过程: 一切以事物的发展流程为中心. 面向对象: 一切以对象为中心,一切皆为对象,具体 ...

  9. day22 01 初识面向对象----简单的人狗大战小游戏

    day22 01 初识面向对象----简单的人狗大战小游戏 假设有一个简单的小游戏:人狗大战   怎样用代码去实现呢? 首先得有任何狗这两个角色,并且每个角色都有他们自己的一些属性,比如任务名字nam ...

  10. python基础(23):面向过程与面向对象的优劣、初识面向对象

    1. 面向过程与面向对象的优劣 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程 ...

随机推荐

  1. Go语言系列之网络编程

    现在我们几乎每天都在使用互联网,我们前面已经学习了如何编写Go语言程序,但是如何才能让我们的程序通过网络互相通信呢?本章我们就一起来学习下Go语言中的网络编程. 关于网络编程其实是一个很庞大的领域,本 ...

  2. Elasticsearch打造全文搜索引擎(一)

     带着问题上路--ES是如何产生的? (1)思考:大规模数据如何检索? 如:当系统数据量上了10亿.100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题: 1)用什么数据库好?(mysq ...

  3. 常用Cron表达式范例

    描述 表达式 每隔5秒执行一次 */5 * * * * ? 每隔1分钟执行一次 0 */1 * * * ? 每天23点执行一次 0 0 23 * * ? 每天凌晨1点执行一次 0 0 1 * * ? ...

  4. 《Go组件设计与实现》-netpoll的总结

    主要针对字节跳动的netpoll网络库进行总结.netpoll网络库相比于go本身的net标准库更适合高并发场景. 基础知识 netpoll与go.net库一样使用epoll这种IO多路复用机制处理网 ...

  5. 12.25 补充总结-jsp标签

    注:标签引用时,需在jsp 头部添加如下语句 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c ...

  6. 【笔记】macos上部署thanos_receiver + thanos_query

    为了方便起见,在mac笔记本上进行了测试 1.写一个发送数据的客户端 package main import ( "fmt" "io/ioutil" " ...

  7. BAT经典面试题之redis的热KEY问题怎么解决

    引言 讲了几天的数据库系列的文章,大家一定看烦了,其实还没讲完...(以下省略一万字).今天我们换换口味,来写redis方面的内容,谈谈热key问题如何解决.其实热key问题说来也很简单,就是瞬间有几 ...

  8. atan2(y,x)和pow(x,y)

    atan2(y,x): 函数atan2(y, x)是4象限反正切,求的是y/x的反正切,其返回值为[-π,+π]之间的一个数.它的取值不仅取决于正切值y/x,还取决于点 (x, y) 落入哪个象限: ...

  9. golang中goroutine

    1. 概念 goroutine 奉行通过通信来共享内存,而不是共享内存来通信 goroutine 是由go的运行时(runtime)调度和管理的 go程序会智能的将goroutine中的任务合理的分配 ...

  10. 003Linux查看文件内容的5个命令姿势

    01 开篇 Linux 中查看文件内容常用的有如下 5 个命令: cat: more: less: tail: head. 02依次看看这些命令的使用姿势 cat 一次性将所有内容输出到屏幕上,方便查 ...