在我们的世界,事物与事物之间总会由一些联系
在面向对象中,类和类之间也可以产生相关关系
1、依赖关系
执行某个动作的时候。需要xxx来帮助你完成这个操作,此时的关系是最轻的
随时可以更换另外一个东西来完成此操作。
View Code
# 植物大战僵尸
View Code
2、一对多关系
继承
View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person: def play(self,tool): # 通过参数的传递,把另一个类传递进来 tool.run() print('玩游戏上天啊') class Computer: def run(self): print('电脑开机') class Phone: def run(self): print('手机解锁') c = Computer() p = Phone() s = Person() s.play(c) s.play(p) # 电脑开机 # 玩游戏上天啊 # 手机解锁 # 玩游戏上天啊
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 植物大战僵尸 class Plant: def __init__(self,name,blood,assault): self.name = name self.blood = blood self.assault = assault def attact(self,ghost): print('植物攻击僵尸') ghost.blood -= self.assault print(f"僵尸掉血{self.assault}还剩下{ghost.blood}") class Ghost: def __init__(self,name,blood,assault): self.name = name self.blood = blood self.assault = assault def attact(self,plant): print('僵尸吃植物') plant.blood -= self.assault print(f"植物掉血{self.assault}还剩下{plant.blood}") p = Plant('妖娆仙人掌',100,300) g = Ghost('铁桶僵尸',1000,20) p.attact(g) g.attact(p) p.attact(g) g.attact(p) p.attact(g)
2、关联关系
在对象里边埋对象
1、一对一关系
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Boy: def __init__(self,name, girlFriend=None): # 在初始化的时候可以给一个对象的属性设置成另一个类的对象 self.girlFriend = girlFriend # 一个男孩有一个女朋友 def eat(self): if self.girlFriend: print(f"带着他的女朋友{self.girlFriend.name}去吃饭") else: print("单身狗,吃什么吃,快去学习") def movie(self): if self.girlFriend: print(f"带着他的女朋友{self.girlFriend.name}去看电影") else: print("单身狗,看什么看,快去学习") class Girl: def __init__(self,name): self.name = name b =Boy("张磊") g = Girl("孙幂") b.eat() b.girlFriend =g b.eat()
2、一对多关系
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class School: def __init__(self,name): self.name = name self.teach_list = [] def employ(self,teacher): self.teach_list.append(teacher) def goclass(self): for i in self.teach_list: i.work() class Teacher: def __init__(self,name): self.name = name def work(self): print(f'{self.name}老师去上课了') s = School('哈佛') t1 = Teacher('zhangmeng') t2 = Teacher('sunxinag') t3 = Teacher('lina') t4= Teacher('zhenjia') t5= Teacher('lixiao') t6 = Teacher('zhouying') t7 = Teacher('huyang') s.employ(t1) s.employ(t2) s.employ(t3) s.employ(t4) s.employ(t5) s.employ(t6) s.employ(t7) s.goclass()
类中的关系:以来关系是最轻的,最终的是继承关系,关联关系是比较微妙的
3、继承关系
子类在不影响父类的程序运行的基础上对父类进行的扩充和扩展,这里我们把父类称为超类或者基类,子类被称为派生类。
我们写好的类和创建的对象,默认都是可哈希的
# 去掉可哈希 class Foo: __hash__ = None # 当前类的对象不可哈希 print(hash(Foo)) # 可哈希 print(hash(Foo())) # TypeError: unhashable type: 'Foo'
self 到底是谁:
self就是你访问方法的那个对象,谁调用的就是谁。类型是根据调用方的对象来进行交换的。
self访问方法的顺序:永远是先找自己,自己的找不到再找父类
super:表示父类
class Foo(): def eat(self,food): print("我爱吃鱼和",food) class Bar: def eat(self,food): print("我爱吃肉和",food) dic = {Foo:"鸡蛋",Bar:"香肠"} for k,v in dic.items(): k().eat(v) # 我爱吃鱼和 鸡蛋 # 我爱吃肉和 香肠 # 类名相当于变量名
继承
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Base: def __init__(self,num): self.num = num def func1(self): print(self.num) self.func2() def func2(self): print(111,self.num) class Foo(Base): def func2(self): print(222,self.num) lst = [Base(1), Base(2),Foo(3)] for obj in lst: obj.func1() # 1 # 111 1 # 2 # 111 2 # 3 # 222 3
特殊成员
__init__() #创建对象的时候初始化操作,构造器 __del__() # 析构器,当一个实例被销毁的时候调用的方法 __call__() # 对象() __getitem__() # 对象[key] __setitem__() # 对象[key] = value __new__() # 创建对象的时候,开辟内存 __enter__() # with对象 as 变量 __exit__() # 结束with的时候 __hash__() # 可哈希 hash() __hash__ = None 干掉可哈希 __str__ 打印对象的时候会自动执行 __delitem__() del对象[key]时执行 __add__() 对象+对象 __doc__ 查看类的描述信息 __module__ 表示当前操作的对象所在模块 __class__ 当前操作对象所处的类 __iter__() 定义迭代器 __contains__(self,item) 定义当使用成员测试运算符(in 活 not in)时的行为
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo: def __init__(self): # 初始化操作 print("我是init, 我是老二") print("初始化操作. 在创建对象的时候自动调用这个方法") def __new__(cls, *args, **kwargs): # 创建, 它是真正的构造方法, 可以开辟内存 print("我是new. 我是老大") return object.__new__(cls) # 为了 对象() def __call__(self, *args, **kwargs): print("我是对象()") # 对象[] def __getitem__(self, item): print("item=",item) print("你执行了__getitem__") return "哈哈" # 对象[key] = value def __setitem__(self, key, value): print("key, ", key) print("value, ", value) # del lst[1] def __delitem__(self, key): print("key=", key) # with 对象: def __enter__(self): print("我是enter") # with 对象: 代码执行完毕. 最后执行这里 def __exit__(self, exc_type, exc_val, exc_tb): print("我叫exit") def __len__(self): print("我的天哪") return 3 f = Foo() # 自动执行__init__() f() # 调用-> __call__() print(callable(f)) # 对象() print(f["李嘉诚"]) # 自动调用__getitem__() f['jay'] = "林俊杰" del f['哈哈'] with f: print("我是哈哈哈哈") with open() : lst = ["孙艺珍", "李金珠", "井柏然"] lst[2] # =>自动的调用__getitem__() def func(): pass func = 3 print(callable(func)) # 判断xxx是否是可调用的 f.__init__() # 第一次这么写. 以后别这么写 lst = [1,2,3,4] it = iter(lst) print(it.__next__()) print(next(it)) # __next__()
面向对象变成的流程
1、加载类 --》 给类创建一个名称空间 --》主要存放类变量
2、创建对象 --》先找类. --》根据类来开辟内存 --》执行类中的 __new__() --》执行 __init__() --》返回对象
首先,在执行类名()的时候。系统会自动限制性__new__()来开辟内存,此时新开辟出来的内存区域是空的,紧随其后,系统自动调用__init__()来完成对象的初始化工作,按照时间轴来算