zoukankan      html  css  js  c++  java
  • 巨蟒python全栈开发-第18天 核能来袭-类和类之间的关系

    一.今日主要内容:

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

    大象进冰箱&植物大战僵尸
    (2)关联关系(在对象里面埋对象)

    老师=>学校
    A.一对一关系 self.girlFriend=girl
    典型案例:你和你的女朋友

    B.一对多关系(生活中,更多的是这种关系) self.teach_list=[t1,t2,t3]
    一个学校,一堆老师

    C.多对多关系

    类中的关系:依赖关系最轻的,最重的是继承关系,关联关系是比较微妙的.

    2.self到底是谁?
    self:谁调用的就是谁.类型是根据调用方的对象来进行变换的(不一定是这个类)
    super:与继承相关的.(表示的是父类)

    3.关联关系=>组合=>聚合=>UML图(一看就会清晰明了了)(类与类之间的关系UML图)

    4.特殊成员:(我们没有主动调用,而是自动调用)
    __init__() #创建对象的时候初始化操作
    __new__() #创建对象的时候,开辟内存

    __call__() #对象()
    __getitem__() #对象['冬瓜']
    __setitem__() #对象['冬瓜']=值
    __hash__() #可哈希 hash()

    __enter__() #with 对象
    __exit__() #结束with的时候

    class A:
    def __init__(self):
    xxxx
    a=A()

    二.今日内容大纲:

    1.依赖关系

    2.关联关系

    3.继承关系

    4.特殊成员

    三.今日内容详解:

    1.依赖关系

    (1)依赖关系例题

    class Person:
        def play(self,tools):     #通过参数的传递把另外一个类的对象传递进来
            tools.run()
            print('很开心,我能玩儿游戏了')
    
    class Computer():
        def run(self):
            print('电脑开机,可以运行')
    
    class Phone():
        def run(self):
            print('手机开机,可以运行了')
    
    c=Computer()
    phone=Phone()
    
    p=Person()
    p.play(phone)

    (2)

    #典型的依赖关系,可以像方法进行缩进优化(思考)
    #这个题目还是有一定的深度的,在攻击力里边的写法
    #写一个植物大战僵尸

    # 1.植物
    # 打僵尸,将是掉血
    # 2.僵尸
    # 吃植物,植物掉血
    #自己写的版本,漏洞很多,思考的灵活性还是不够
    class plant():
        def __init__(self,name,blood,gjl):
            self.name=name
            self.blood=blood
            self.gjl=gjl
    
        def skill(self,js):
            js.blood-=self.gjl
            print(f'僵尸掉血{self.gjl},还剩下{js.blood}')
    
    class jiangshi():
    
        def __init__(self,name,blood,gjl):
            self.name=name
            self.blood=blood
            self.gjl=gjl
    
        def j_skill(self,zw):
            zw.blood-=self.gjl
            print(f'植物掉血{self.gjl},还剩下{zw.blood}')
    
    zhiwu=plant('大冬瓜',100,1)
    js=jiangshi('小僵尸',20,2)
    
    zhiwu.skill(js)
    js.j_skill(zhiwu)
    
    # pjf=pj_fight()
    # pjf.play(zhiwu)
    
    #老师讲解
    
    class plant():
        def __init__(self,name,hp,ad):
            self.name = name
            self.hp = hp
            self.ad = ad
    
        def attack(self,js):    #注意这里需要名字js
            print('植物攻击僵尸')
            js.hp-=self.ad
            print(f'僵尸掉血{self.ad},还剩下{js.hp}')
    
    class jiangshi():
    
        def __init__(self,name,hp,ad):
            self.name = name
            self.hp = hp
            self.ad = ad
    
        def attack(self,zw):
            print('僵尸咬植物')
            zw.hp-=self.ad
            print(f"植物掉血{self.ad},还剩{zw.hp}")
    
    wd = plant('大冬瓜', 100, 1)
    js = jiangshi('小僵尸', 20, 2)
    
    wd.attack(js)
    wd.attack(js)
    wd.attack(js)
    
    js.attack(wd)
    js.attack(wd)
    js.attack(wd)
    js.attack(wd)
    
    #人狗大战&西门庆与武松大战都可以写了

    2.关联关系

    (1)一对一关系

    class Boy:
        def __init__(self,name,girlFriend=None):
            #在初始化的时候可以给一个对象的属性设置成另一个 类的对象
            self.name=name
            self.girlFriend=girlFriend      #一个男孩有一个女朋友
    
        def chi(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.chi()
    
    #第二步
    #alex给宝浪介绍了一个女朋友,孙艺珍
    b=Boy('宝浪')
    g=Girl('孙艺珍')
    b.girlFriend=g
    b.chi()
    
    #第三步
    b=Boy('宝浪')
    g=Girl('孙艺珍')
    g2=Girl('梁咏琪')      #在这里换了女朋友
    b.girlFriend=g2       #换了个女朋友
    b.chi()

    (2)

    #一对多关系(使用率最高的关系),超级重点
    #这个通过列表的创建,列表的添加,for循环列表
    #与 初始化,招聘老师,上课老师 进行方法对应
    class School():
        def __init__(self,name):
            self.teach_list=[]  #这里要装多个老师
                                #注意这里搞了一个列表             #创建
            self.name=name
            self.hehe='呵呵'
            #初始化时候,可以给一些属性
    
        def zhaopin(self,teach):                                  #添加
            self.teach_list.append(teach)
    
        def shangke(self):
            for t in self.teach_list:                           #循环执行
                t.work()
    class Teacher:
        def __init__(self,name):
            self.name=name
        def work(self):
            print(f'{self.name}在上课')
    
    lnh=School('老男孩')
    t1=Teacher('武sir')
    t2=Teacher('太白')
    t3=Teacher('哪吒')
    t4=Teacher('女神')
    t5=Teacher('日天')
    t6=Teacher('宝浪')
    
    lnh.zhaopin(t1)                                             #在这个地方添加的是实例化后的对象
    lnh.zhaopin(t2)
    lnh.zhaopin(t3)
    lnh.zhaopin(t4)
    lnh.zhaopin(t5)
    lnh.zhaopin(t6)
    
    lnh.shangke()   #一执行,就把上边的全部执行了
                      #因为上课中用到的是for遍历列表中的细信息

    3.继承关系

    (1)

    class Base:
        def chi(self):
            print('我会吃')
    
    #派生类=>就是子类
    class Foo(Base):   #这个类继承了Base类,Foo类是对Base的一个扩展
        def he(self):
            print('我会喝')
    f=Foo()
    f.chi()
    f.he()

    (2)

    #注意名称的描述
    class Cat:  #父类=>基类(超类)
        def catch_mouse(self):
            print("猫可以抓老鼠")
    
    class BosiCat(Cat): #子类=>派生类
        pass

    (3)

    class Foo:
        pass
    print(hash(Foo))    #可哈希
    print(hash(Foo()))  #可哈希
    
    #总结:我们写好的类和创建的对象默认都是可哈希的
    
    class Foo:
        __hash__=None
    print(hash(Foo))        #可哈希
    print(hash(Foo()))      #unhashable type: 'Foo'
    
    #类永远是可哈希的,但是加上__hash__=None,
    # 对象就不可哈希了

    (4)

    #利用字典进行调用
    class Foo:
        def chi(self):
            print('我爱吃鱼')
    class Bar:
        def chi(self):
            print('我爱吃肉')
    dic ={Foo:Foo(),Bar:Bar()}
    
    for k,v in dic.items():
        v.chi()

    (5)

    #利用字典调用=>升级
    class Foo:
        def chi(self,food):
            print('我爱吃鱼和',food)
    class Bar:
        def chi(self,food):
            print('我爱吃肉和',food)
    dic ={Foo:'鸡蛋',Bar:'香肠'}
    
    for k,v in dic.items():
        k().chi(v)

    (6)self系列

    # self中 先找自己的,再找父类的
    
    #对比函数进行回顾:
    # 类名  => 变量名 ->相同的道理
    # def func():
    #     pass
    #
    # an = func
    # an()
    View Code
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
    class Foo(Base):
        pass
    obj = Foo(123)
    obj.func1()
    
    '''
    结果:
    123
    '''
    View Code
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
    
    class Foo(Base):
        def func1(self):
            print("Foo. func1", self.num)
    
    obj = Foo(123)
    obj.func1()
    
    '''
    结果:
    Foo. func1 123
    '''
    View Code
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
            self.func2()
        def func2(self):
            print("Base.func2")
    
    class Foo(Base):
        def func2(self):
            print("Foo.func2")
    obj = Foo(123)
    obj.func1()
    
    '''
    结果:
    123
    Foo.func2
    '''
    View Code
    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.func2()
    
    '''
    结果:
    111 1
    111 2
    222 3
    '''
    View Code
    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
    '''
    View Code

    4.特殊成员

    (1)

    class Foo:
        def __init__(self):
            print('初始化操作,在创建对象的时候自动调用这个方法')
    
    f=Foo()     #自动执行__init__()
    f.__init__()    #第一次这么写,以后不要这么写
    
    #上边两行是等价的

    (2)

    # 回顾:三大器1
    # lst=[]
    # lst.__iter__()
    
    #回顾内置函数
    # lst=[1,2,3,4]
    # it=iter(lst)
    # print(it.__next__())
    # print(next(it))

    (3)

    #callable  可调用的  判断xxx是否是可调用的
    
    # 曾经的例子:
    # def func():
    #     pass
    # print(callable(func))
    # func=3
    # print(callable(func))   #此时变成不可调用的
    
    # class Foo:
    #     def __init__(self):
    #         print('初始化操作,在创建对象的时候自动调用这个方法')
    # f=Foo()             #结果:初始化操作,在创建对象的时候自动调用这个方法
    # print(callable(f))  #False  说明对象不可调用
    #
    
    #__call__()的作用:
    # class Foo:
    #     def __init__(self):
    #         print('初始化操作,在创建对象的时候自动调用这个方法')
    #
    #     #为了对象能够被调用而生的    f()
    #     def __call__(self, *args, **kwargs):
    #         print('我是对象()')
    # f=Foo()                     #初始化操作,在创建对象的时候自动调用这个方法
    # f()                         #我是对象(),   调用的是__call__内的东西
    # print(callable(f))          #True

    (4)

    #__getitem__   字典,元组,列表都是用的这个  (给值)
    
    # class Foo:
    #     #对象[]
    #     def __getitem__(self, item):
    #         print('item=',item)
    #         print('你执行了__getitem__')
    #         return  '哈哈'
    # f=Foo()                     #初始化操作,在创建对象的时候自动调用这个方法
    # print(f['李嘉诚'])
    
    '''
    结果:
    item= 李嘉诚
    你执行了__getitem__
    哈哈
    '''

    (5)

    #__setItem__()方法
    
    # class Foo:
    #     def __setitem__(self, key, value):
    #         print("key, ", key)
    #         print("value, ", value)
    # f=Foo()
    # f['jay'] = "林俊杰"
    
    '''
    结果:
    key,  jay
    value,  林俊杰
    '''

    (6)

    # __delitem__()方法
    
    # class Foo:
    #     def __delitem__(self, key):
    #         print('key=',key)
    # f=Foo()
    # del f['哈哈']
    
    '''
    结果:
    key= 哈哈
    '''

    (7)

    # __enter__() 方法
    #__exit__()方法
    
    # class Foo:
    # # with 对象:
    #     def __enter__(self):
    #         print("我是enter")
    #     # with 对象: 代码执行完毕. 最后执行这里
    #     def __exit__(self, exc_type, exc_val, exc_tb):
    #         print("我叫exit")
    # f=Foo()
    # with f:
    #     print("我是哈哈哈哈")
    
    '''
    结果:
    我是enter
    我是哈哈哈哈
    我叫exit
    '''

    (8)

    # class Foo:
    #     def __init__(self): # 初始化操作
    #         print("我是init,  我是老二")
    #         print("初始化操作. 在创建对象的时候自动调用这个方法")
    #
    #     def __new__(cls, *args, **kwargs): # 创建, 它是真正的构造方法,  可以开辟内存
    #         print("我是new. 我是老大")  #在开辟内存之前可以放东西
    #         return object.__new__(cls)

    (9)

    # lst = ["孙艺珍", "李金珠", "井柏然"]
    #
    # lst[2] # =>自动的调用__getitem__()

    (10)

    面向对象编程的执行流程=>
    1.加载类=>给类创建一个名称空间=>主要存放类变量
    2.创建对象=>先找类=>根据类来开辟内存=>
    执行类中的__new__() -> 执行__init__() -> 返回对象

    (11)

    #__str__()  and __repr__()
    class Student:
        def __init__(self,name,no,gender,cls,age):
            self.name=name
            self.no=no
            self.gender=gender
            self.cls=cls
            self.age=age
    
          # 遇到出不来,两个都尝试一下
          # 如果只是内存地址,再写另一个试试
        #这个对象字符串的表示
        # def __str__(self):   #返回该对象的字符串表示形式
        #     return f'{self.name},{self.no},{self.gender}'
    
        # def __repr__(self):     #该对象的官方的字符串表示形式
        #     return f'{self.name},{self.no},{self.gender}'
    s = Student("冬瓜", "3", "", "S18", "31")
    print(s)

    作业讲解:记得补充:

  • 相关阅读:
    firefox安装教程
    shell脚本介绍
    vue 图片引入
    vscode 常用插件
    vscode 打不开chrome浏览器解决方案
    win10 wifi 密码查看
    爽文 主角如 石昊 白小纯 方行 秦牧 楚风
    codepen, jsrun 使用iframe嵌入
    uniapp 自定义扫一扫页面
    数组(遍历删除多个元素)
  • 原文地址:https://www.cnblogs.com/studybrother/p/10144682.html
Copyright © 2011-2022 走看看