在我们的世界,事物与事物之间总会由一些联系
在面向对象中,类和类之间也可以产生相关关系
 
1、依赖关系
        执行某个动作的时候。需要xxx来帮助你完成这个操作,此时的关系是最轻的
        随时可以更换另外一个东西来完成此操作。
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)

# 电脑开机
# 玩游戏上天啊
# 手机解锁
# 玩游戏上天啊
View Code
# 植物大战僵尸
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、一对一关系
 
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()
View Code

    2、一对多关系 

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()
2、一对多关系
    类中的关系:以来关系是最轻的,最终的是继承关系,关联关系是比较微妙的
 
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)
    
# 我爱吃鱼和 鸡蛋
# 我爱吃肉和 香肠

# 类名相当于变量名

继承 

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)  定义当使用成员测试运算符(innot in)时的行为

 

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__()
View Code
 
面向对象变成的流程
1、加载类 --》 给类创建一个名称空间 --》主要存放类变量
2、创建对象 --》先找类. --》根据类来开辟内存 --》执行类中的 __new__() --》执行 __init__()  --》返回对象
 
首先,在执行类名()的时候。系统会自动限制性__new__()来开辟内存,此时新开辟出来的内存区域是空的,紧随其后,系统自动调用__init__()来完成对象的初始化工作,按照时间轴来算
 
posted on 2018-12-19 22:00  古鲁月  阅读(397)  评论(0编辑  收藏  举报