对象的相关知识
回到咱们的人狗大战:现在我们需要对我们的类做出一点点改变
人类除了可以走路之外,还应该具备一些攻击技能。
class Person: # 定义一个人类
role = 'person' # 人的角色属性都是人
def __init__(self, name, aggressivity, life_value):
self.name = name # 每一个角色都有自己的昵称;
self.aggressivity = aggressivity # 每一个角色都有自己的攻击力;
self.life_value = life_value # 每一个角色都有自己的生命值;
def attack(self,dog):
# 人可以攻击狗,这里的狗也是一个对象。
# 人攻击狗,那么狗的生命值就会根据人的攻击力而下降
dog.life_value -= self.aggressivit
对象是关于类而实际存在的一个例子,即实例
对象/实例只有一种作用:属性引用
egg = Person(‘egon’,10,1000)
print(egg.name)
print(egg.aggressivity)
print(egg.life_value)
当然了,你也可以引用一个方法,因为方法也是一个属性,只不过是一个类似函数的属性,我们也管它叫动态属性。
引用动态属性并不是执行这个方法,要想调用方法和调用函数是一样的,都需要在后面加上括号
print(egg.attack)
我知道在类里说,你可能还有好多地方不能理解。那我们就用函数来解释一下这个类呀,对象呀到底是个啥,你偷偷的用这个理解就好了,不要告诉别人
帮你了解面向对象
面向对象小结——定义及调用的固定模式
小结
练一练
回到顶部
对象之间的交互
现在我们已经有一个人类了,通过给人类一些具体的属性我们就可以拿到一个实实在在的人。
现在我们要再创建一个狗类,狗就不能打人了,只能咬人,所以我们给狗一个bite方法。
有了狗类,我们还要实例化一只实实在在的狗出来。
然后人和狗就可以打架了。现在我们就来让他们打一架吧!
创建一个狗类
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):
# 狗可以咬人,这里的狗也是一个对象。
# 狗咬人,那么人的生命值就会根据狗的攻击力而下降
dog.life_value -= self.aggressivit
实例化一只实实在在的二哈
ha2 = Dog(‘二愣子’,‘哈士奇’,10,1000) #创造了一只实实在在的狗ha2
交互 egon打ha2一下
print(ha2.life_value) #看看ha2的生命值
egg.attack(ha2) #egg打了ha2一下
print(ha2.life_value) #ha2掉了10点血
完整的代码
egon大战哈士奇
一个简单的例子帮你理解面向对象
回到顶部
类命名空间与对象、实例的命名空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
而类有两种属性:静态属性和动态属性
静态属性就是直接在类中定义的变量
动态属性就是定义在类中的方法
其中类的数据属性是共享给所有对象的
id(egg.role)
4341594072id(Person.role)
4341594072
而类的动态属性是绑定到所有对象的
egg.attack
<bound method Person.attack of <main.Person object at 0x101285860>>Person.attack
<function Person.attack at 0x10127abf8>
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类…最后都找不到就抛出异常
回到顶部
面向对象的组合用法
软件重用的重要方式除了继承之外还有另外一种方式,即:组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
class Weapon:
def prick(self, obj): # 这是该装备的主动技能,扎死对方
obj.life_value -= 500 # 假设攻击力是500
class Person: # 定义一个人类
role = 'person' # 人的角色属性都是人
def __init__(self, name):
self.name = name # 每一个角色都有自己的昵称;
self.weapon = Weapon() # 给角色绑定一个武器;
egg = Person('egon')
egg.weapon.prick()
#egg组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法
圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用
from math import pi
class Circle:
'''
定义了一个圆形类;
提供计算面积(area)和周长(perimeter)的方法
'''
def __init__(self,radius):
self.radius = radius
def area(self):
return pi * self.radius * self.radius
def perimeter(self):
return 2 * pi *self.radius
circle = Circle(10) #实例化一个圆
area1 = circle.area() #计算圆面积
per1 = circle.perimeter() #计算圆周长
print(area1,per1) #打印圆面积和周长
class Ring:
'''
定义了一个圆环类
提供圆环的面积和周长的方法
'''
def __init__(self,radius_outside,radius_inside):
self.outsid_circle = Circle(radius_outside)
self.inside_circle = Circle(radius_inside)
def area(self):
return self.outsid_circle.area() - self.inside_circle.area()
def perimeter(self):
return self.outsid_circle.perimeter() + self.inside_circle.perimeter()
ring = Ring(10,5) #实例化一个环形
print(ring.perimeter()) #计算环形的周长
print(ring.area()) #计算环形的面积
复制代码
复制代码
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程
复制代码
复制代码
class BirthDate:
def __init__(self,year,month,day):
self.year=year
self.month=month
self.day=day
class Couse:
def __init__(self,name,price,period):
self.name=name
self.price=price
self.period=period
class Teacher:
def __init__(self,name,gender,birth,course):
self.name=name
self.gender=gender
self.birth=birth
self.course=course
def teach(self):
print('teaching')
p1=Teacher('egon','male',
BirthDate('1995','1','27'),
Couse('python','28000','4 months')
)
print(p1.birth.year,p1.birth.month,p1.birth.day)
print(p1.course.name,p1.course.price,p1.course.period)
'''
运行结果:
1 27
python 28000 4 months
'''
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
回到顶部
初识面向对象小结
定义一个人类
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不敌狡猾的人类用武器取胜,血槽空了一半
按照这种思路一点一点的设计类和对象,最终你完全可以实现一个对战类游戏。