一、类的名称空间以及对象名称空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
类的两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量(字段)
- 动态属性就是定义在类中的方法
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
class Gamerole(object): name = 'LOL' year = 2012 def __init__(self,name,ad,hp): self.name = name self.ad = ad self.hp = hp def attack(self,p1): # Gamerole.area = '德玛西亚' p1.hp -= self.ad print('%s攻击%s,%s掉了%s血,还剩%s血' % (self.name, p1.name, p1.name, self.ad, p1.hp))
gailun = Gamerole('草丛伦',10,200) # 实例化一个对象
gailun.armor = 90 # {'name': '草丛伦', 'ad': 10, 'hp': 200, 'armor': 90} print(gailun.__dict__) # 对象的属性:不仅在__init__里面添加,还可以在其他方法或者类外面添加。
yasuo = Gamerole('托儿所', 20, 50) yasuo.attack(gailun) # 托儿所攻击草丛伦,草丛伦掉了20血,还剩180血
# 类的属性:不仅在类内部可以添加,还可以在类外部添加。
gailun = Gamerole('草丛伦', 10, 200) timo = Gamerole('提莫', 30, 60) print(gailun.name) # 草丛伦 # 对象空间中存在一个类对象指针,所以对象可以找到类中的变量以及方法
print(gailun.year)
# 类名只能找到类中的变量,方法,或者(父类中的),不能找对象中的属性。
二、组合
# 计算一个类被多少人执行过。
count = 0 class A: def __init__(self): global count count += 1 class B: count = 0 def __init__(self): B.count += 1 obj = B() print(obj.count) obj = B() print(obj.count) obj = B() obj = B() obj = B() obj = B() print(B.count)
# 组合: 将一个对象封装到另一个对象的属性中
例子: class Gamerole: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self, p1): p1.hp -= self.ad print("%s攻击%s,%s掉了%s血,还剩%s血" % (self.name, p1.name, p1.name, self.ad, p1.hp)) def equip_weapon(self, wea): self.wea = wea # 组合:给一个对象封装另一个对象的属性 class Weapon: def __init__(self, name, ad): self.name = name self.ad = ad def weapon_attack(self, p1, p2): p2.hp = p2.hp - self.ad - p1.ad print("%s 利用 %s 攻击了 %s,%s 还剩 %s 血" % (p1.name, self.name, p2.name, p2.name, p2.hp)) barry = Gamerole('太白', 10, 200) panky = Gamerole('金莲', 20, 50) pillow = Weapon('绣花枕头', 2) # pillow.weapon_attack(barry, panky) barry.equip_weapon(pillow) barry.wea.weapon_attack(barry, panky)
组合的好处
1,代码更好。
2,类与类之间的耦合性增强。
三、面向对象的三大特征:继承
class Animal: type_name = "动物类" def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age def eat(self): print(self) print('吃东西') class Person(Animal): type_name = "人类" # 自己有就不要向父级拿 pass class Cat(Animal): pass class Dog(Animal): pass
print(Person.type_name) # 人类
Animal 叫父类,基类。 Person、Cat、Dog : 子类,派生类
继承:单继承,多继承
python 类:
经典类:只存在python2x,不继承object的类,所以python2x既有经典类,又有新式类
新式类:继承object类。python3x所有类默认都继承object。
经典类:深度优先。
新式类:mro 继承顺序,c3 算法。
# 既要执行父类方法,又要执行子类方法
class Animal: type_name = "动物类" def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age def eat(self): print(self) print('吃东西') class Person(Animal): def __init__(self, name, sex, age, mind): Animal.__init__(self, name, sex, age) # 方法一 super().__init__(name, sex, age) # 方法二 self.mind = mind # type_name = "人类" pass class Cat(Animal): def __init__(self, name, sex, age, climb): Animal.__init__(self, name, sex, age) self.climb = climb pass class Dog(Animal): def __init__(self, name, sex, age, shit): Animal.__init__(self, name, sex, age) self.shit = shit pass 方法一 : Animal.__init__ p1 = Person('春哥', "男", 20, '有思想') print(p1.__dict__) p2 = Cat('小花', '女', 5, '能爬树') print(p2.__dict__) p3 = Cat('大黄', '男', 8, '会吃肉') print(p3.__dict__)
# 方法一: Aniaml.__init__(self,name,sex,age) # p1 = Person('春哥','laddboy',18,'有思想') # print(p1.__dict__) # 方法二:super # p1 = Person('春哥','laddboy',18,'有思想') # print(p1.__dict__) # def func(self): # pass # self = 3 # func(self)
# p1 = Person('春哥','laddboy',18,'有思想')
# p1.eat()
继承 的特点:
1,类与类之间的耦合性增强。
2,节省代码。
3,代码更加规范化,合理性。
练习:
Day19天作业及默写
1,暴力摩托程序(完成下列需求):
1.1
创建三个游戏人物,分别是:
①苍井井,女,18,攻击力ad为20,血量200
②东尼木木,男,20,攻击力ad为30,血量150
③波多多,女,19,攻击力ad为50,血量80
1.2
创建三个游戏武器,分别是:
①平底锅,ad为20
②斧子,ad为50
③双节棍,ad为65
1.3
创建三个游戏摩托车,分别是:
①小踏板,速度60迈
②雅马哈,速度80迈
③宝马,速度120迈。
class Game_role: def __init__(self,name,sex,age,ad,hp): self.name = name self.sex = sex self.age = age self.ad = ad self.hp = hp def equit_Moto(self, mo): self.mo = mo def equit_weapon(self, wea): self.we = wea def attack(self, p1): p1.hp = p1.hp - self.ad print('%s赤手空拳打了%s%s滴血,%s还剩%s血。' % (self.name, p1.name, self.ad, p1.name, p1.hp)) class Weapon: def __init__(self, name, ad): self.name = name self.ad = ad def attack_wea(self, p1, p2): p2.hp = p2.hp - p1.ad - self.ad print('%s利用%s打了%s一%s,%s还剩%s血。' %(p1.name, self.name, p2.name, self.name, p2.name, p2.hp)) def mixed_attack(self,p1,p2): p2.hp = p2.hp - p1.ad - self.ad print('%s骑着%s打了骑着%s的%s一%s,%s哭了,还剩%s血。' % (p1.name, p1.mo.name, p2.mo.name, p2.name, self.name, p2.name, p2.hp)) class Moto: def __init__(self,name,speed): self.name = name self.speed = speed def run(self,p1): print('%s骑着%s开着%s迈的车行驶在赛道上' %(p1.name,self.name,self.speed)) cang = Game_role('苍井井','女',18,20,200) dongni = Game_role('东尼木木', '男', 20, 30, 150) boduo = Game_role('波多多', '女', 19, 50, 80) pan = Weapon('平底锅', 20) axe = Weapon('斧子', 50) nunchakus = Weapon('双节棍', 20) pedal = Moto('小踏板', 60) yamaha = Moto('雅马哈', 80) bmw = Moto('宝马', 120)
完成下列需求(利用武器打人掉的血量为武器的ad + 人的ad):
(1)苍井井骑着小踏板开着60迈的车行驶在赛道上。
(2)东尼木木骑着宝马开着120迈的车行驶在赛道上。
(3)波多多骑着雅马哈开着80迈的车行驶在赛道上。
(4)苍井井赤手空拳打了波多多20滴血,波多多还剩xx血。
(5)东尼木木赤手空拳打了波多多30滴血,波多多还剩xx血。
(6)波多多利用平底锅打了苍井井一平底锅,苍井井还剩xx血。
(7)波多多利用斧子打了东尼木木一斧子,东尼木木还剩xx血。
(8)苍井井骑着宝马打了骑着小踏板的东尼木木一双节棍,东尼木木哭了,还剩xx血。(选做)
cang.equit_Moto(bmw)
cang.equit_weapon(nunchakus)
dongni.equit_Moto(pedal)
(9)波多多骑着小踏板打了骑着雅马哈的东尼木木一斧子,东尼木木哭了,还剩xx血。(选做)
2,
a, 定义一个父类Animal,在构造方法中封装三个属性,姓名,性别,年龄,再给其添加一个eat的方法,方法中显示 % s正在吃饭( % s是哪个对象调用此方法,显示哪个对象名字)。
b, 定义两个基类Person, Dog,全部继承这个父类Animal.
c, Person类中,有构造方法,封装一个皮肤的属性,有eat方法,方法中显示人类正在吃饭。
d, Dog类中,有构造方法,封装一个毛色的属性,有eat方法,方法中显示狗狗正在吃饭。
class Animal(object): def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age def eat(self): print("%s正在吃饭, 吃完饭喂狗" % self.name) class Person(Animal): def __init__(self, skin, name, sex, age): self.skin = skin super().__init__(name, sex, age) # def eat(self): # print("人类正在吃饭") class Dog(Animal): def __init__(self, coat, name, sex, age): self.coat = coat super().__init__(name, sex, age) def eat(self): super().eat() print("狗狗正在吃饭")
上面这几个类创建完成之后,完成下列要求:
①: 实例化一个人类的对象,让其只封装皮肤属性。
②: 实例化一个人类的对象,让其封装姓名,性别,年龄,皮肤四个属性。
③: 实例化一个狗类的对象,让其只封装毛色属性。
obj_dog = Dog("黑白相间") print(obj_dog.__dict__)
④: 实例化一个狗类的对象,让其封装姓名,性别,年龄,毛色四个属性。
obj_dog1 = Dog("黑白相间", "二哈", "公", 2) print(obj_dog1.__dict__)
⑤: 实例化一个人类的对象,让其只执行父类的eat方法(可以对人类代码进行修改)。
⑥: 实例化一个狗类的对象,让其既执行父类的eat方法,又执行子类的eat方法。
obj_dog1 = Dog("黑白相间", "大黄", "母", 3) obj_dog1.eat()
3,定义一个类,计算圆的周长和面积。
from math import pi class Circle: def __init__(self, r): self.r = r def perimeter(self): return 2 * pi * self.r def area(self): return pi * (self.r ** 2) obj_circle = Circle(18) print(obj_circle.perimeter()) print(obj_circle.area())
4,定义一个圆环类,计算圆环的周长和面积(升级题)。
class Ring: def __init__(self, b_r, s_r): self.b_r = b_r self.s_r = s_r def perimeter(self): return 2 * pi * self.b_r + 2 * pi * self.s_r # 大圆的周长 + 小圆的周长 # return 2 * pi * (self.b_r + self.s_r) def area(self): return pi * self.b_r ** 2 - pi * self.s_r ** 2 # 大圆面积 - 小圆面积 obj_ring = Ring(30, 18) print(obj_ring.perimeter()) print(obj_ring.area())