面向对象进阶:命名空间和组合
面向对象的命名空间
属性:静态属性(直接和类名关联的对象或者直接定义在class下的变量)、对象属性(在类内和self关联,在类外和对象名关联的变量)
类名操作变量 不管操作可变还是不可变数据类型 都是类中对应的变量发生变化
对象名操作静态变量
引用变量:先在自己的命名空间中查找,找不到就去类的命名空间找
修改变量:
如果是对可变数据类型中的元素进行修改,那么全局生效
如果是对变量进行重新赋值,那么只是在对象自己的命名空间里增加了一个新的属性
class Foo: country = 'China' country_lst = ['China'] def __init__(self,name): self.name = name alex = Foo('alexander') egg = Foo('egon') alex.age = 90 Foo.role = 'Person' print(Foo.country) print(alex.name) print(egg.name) print(alex.country) print(alex.role) alex.country = '印度' print(alex.country) # 印度 print(egg.country) # China print(Foo.country) # China del alex.country alex.country_lst.append('印度') print(alex.country_lst) # ['China', '印度'] print(egg.country_lst) # ['China', '印度'] print(Foo.country_lst) # ['China', '印度']
设计一个类,统计这个类被实例化的次数,且所有的对象共享这个属性
class Foo: count = 0 def __init__(self): Foo.count += 1 f1 = Foo() f2 = Foo() print(f1.count)
对象使用名字的顺序:先用自己的,再用类的
对象可以使用类的
而类无法使用对象的
组合
组合:什么有什么的关系
一个对象的属性是另外一个类的对象
class Teacher: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex # 老师有生日:年月日 class Birthday: def __init__(self,year,month,day): self.year = year self.month = month self.day = day birthday1 = Birthday(1968,12,31) boss_gold = Teacher('太亮',40,'不详') boss_gold.birth = birthday1 boss_gold.birth.year # 将一个类的对象拥有的属性 再将其定义成一个类以提高代码的复用 class Teacher: def __init__(self,name,age,sex,year,month,day): self.name = name self.age = age self.sex = sex self.birth = Birthday(year,month,day) class Birthday: def __init__(self,year,month,day): self.year = year self.month = month self.day = day boss_gold = Teacher('太亮',40,'不详',1968,12,31)
圆和圆环
from math import pi class Circle: def __init__(self,r): self.r = r def perimeter(self): return pi*self.r*2 def area(self): return pi*self.r*self.r class Ring: def __init__(self,outer_r,inner_r): self.outer_circle = Circle(outer_r) self.inner_circle = Circle(inner_r) def perimeter(self): return self.outer_circle.perimeter()+self.inner_circle.perimeter() def area(self): return self.outer_circle.area()-self.inner_circle.area() r1 = Ring(10,5) print(r1.area())
人狗大战组合
class 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,person): person.life_value -= self.aggressivity class 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 def get_weapon(self,weapon_obj): if self.money > weapon_obj.price: self.money -= weapon_obj.price self.weapon = weapon_obj self.aggressivity += weapon_obj.aggr boss_gold = Person('金老板',5,250,100) huang = Dog('大黄','藏獒',100,3000) huang.bite(boss_gold) print(boss_gold.life_value) # 人有武器——组合 class Weapon: def __init__(self,name,price,aggr): self.name = name self.price = price self.aggr = aggr dgb = Weapon('打狗棒',99.8,100) boss_gold.get_weapon(dgb)
继承
继承:至少两个类 什么是什么的关系,为了避免几个类之间有相同的代码
父类:Animal
子类:Dog、Person
class Animal: def __init__(self,name, aggressivity, life_value): self.name = name self.aggressivity = aggressivity self.life_value = life_value class Dog(Animal): def bite(self,person): person.life_value -= self.aggressivity class Person(Animal): def attack(self,dog): dog.life_value -= self.aggressivity huang = Dog('大黄',100,3000) # __init__ 找父类 boss_gold = Person('金',10,100)
查看继承的类
print(Dog.__bases__) # (<class '__main__.Animal'>,) print(Animal.__bases__) # (<class 'object'>,)
python两种类:经典类 新式类
python3 所有类都是新式类——都默认继承object class Animal(object): == class Animal:
python2 经典类和新式类并存:
class Animal: 经典类 —— 继承顺序 个别使用方法
class Animal(object): 新式类
两个类中有相同的代码
继承:把相同的代码放在父类中,子类的对象在子类中没有找到方法的时候,使用父类的
单继承和多继承
class ParentClass1: #定义父类 pass class ParentClass2: #定义父类 pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 pass
父类 超类 基类
子类 派生类
抽象和继承