一、类的名称空间以及对象名称空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
类的两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量(字段)
- 动态属性就是定义在类中的方法
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
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迈。
完成下列需求(利用武器打人掉的血量为武器的ad + 人的ad):
(1)苍井井骑着小踏板开着60迈的车行驶在赛道上。
(2)东尼木木骑着宝马开着120迈的车行驶在赛道上。
(3)波多多骑着雅马哈开着80迈的车行驶在赛道上。
(4)苍井井赤手空拳打了波多多20滴血,波多多还剩xx血。
(5)东尼木木赤手空拳打了波多多30滴血,波多多还剩xx血。
(6)波多多利用平底锅打了苍井井一平底锅,苍井井还剩xx血。
(7)波多多利用斧子打了东尼木木一斧子,东尼木木还剩xx血。
(8)苍井井骑着宝马打了骑着小踏板的东尼木木一双节棍,东尼木木哭了,还剩xx血。(选做)
(9)波多多骑着小踏板打了骑着雅马哈的东尼木木一斧子,东尼木木哭了,还剩xx血。(选做)
2,
a, 定义一个父类Animal,在构造方法中封装三个属性,姓名,性别,年龄,再给其添加一个eat的方法,方法中显示 % s正在吃饭( % s是哪个对象调用此方法,显示哪个对象名字)。
b, 定义两个基类Person, Dog,全部继承这个父类Animal.
c, Person类中,有构造方法,封装一个皮肤的属性,有eat方法,方法中显示人类正在吃饭。
d, Dog类中,有构造方法,封装一个毛色的属性,有eat方法,方法中显示狗狗正在吃饭。
上面这几个类创建完成之后,完成下列要求:
①: 实例化一个人类的对象,让其只封装皮肤属性。
②: 实例化一个人类的对象,让其封装姓名,性别,年龄,皮肤四个属性。
③: 实例化一个狗类的对象,让其只封装毛色属性。
④: 实例化一个狗类的对象,让其封装姓名,性别,年龄,毛色四个属性。
⑤: 实例化一个人类的对象,让其只执行父类的eat方法(可以对人类代码进行修改)。
⑥: 实例化一个狗类的对象,让其既执行父类的eat方法,又执行子类的eat方法。
3,定义一个类,计算圆的周长和面积。
4,定义一个圆环类,计算圆环的周长和面积(升级题)。