zoukankan      html  css  js  c++  java
  • python类与类之间的关系

    在面向对象中,类和类之间也可以产生相关的关系
    类中的关系: 依赖关系是最轻的,最重的是继承关系,关联关系是比较微妙的

    依赖关系
    执行某个动作的时候,需要xxx来帮助完成这个操作,此时的关系是最轻的.
    随时可以更换另外一个东西来完成此操作

    class Person:
        def f1(self,tools):     # 通过参数的传递把另外一个类的对象传递进来
            tools.run()
            print('皮一下很开心')
    class Computer:
        def run(self):
            print('电脑开机运行')
    class Phone:
        def run(self):
            print('手机开机')
    c = Computer()
    a = Phone()
    p = Person()
    p.f1(a)         #把Phone类的对象a传递给Person的f1方法作为参数
    结果
    手机开机
    皮一下很开心
    
    事例二
    植物大战僵尸
    class Plant:
        def __init__(self,hp,ad):
            self.hp = hp
            self.ad = ad
        def attack(self,js):
            print('植物攻击僵尸')
            js.hp -= self.ad
            print(f'僵尸掉血{self.ad},剩余{js.hp}')
    class JiangShi:
        def __init__(self,hp,ad):
            self.hp = hp
            self.ad = ad
        def attack(self,zw):
            print('僵尸咬植物')
            zw.hp -= self.ad
            print(f'植物掉血{self.ad},剩余{zw.hp}')
    zw = Plant(100,11)
    js = JiangShi(80,15)
    zw.attack(js)
    zw.attack(js)
    js.attack(zw)
    js.attack(zw)
    结果
    植物攻击僵尸
    僵尸掉血11,剩余69
    植物攻击僵尸
    僵尸掉血11,剩余58
    僵尸咬植物
    植物掉血15,剩余85
    僵尸咬植物
    植物掉血15,剩余70

    关联关系
    对象里面包含对象

    一对一关系
    class Boy:
        def __init__(self,name,girFriend=None):
            self.name = name
            self.girFriend = girFriend
        def play(self):
            if self.girFriend:
                print(f'{self.name}带着他女朋友{self.girFriend.name}去吃饭')
            else:
                print('单身狗,还吃什么饭')
        def movie(self):
            if self.girFriend:
                print(f'{self.name}带着他女朋友{self.girFriend.name}去看电影')
            else:
                print('单身狗,还看什么电影')
    class Girl:
        def __init__(self,name):
            self.name = name
    b = Boy('刘昊然')
    g = Girl('刘丽')
    b.play()
    
    b.girFriend = g
    b.play()
    
    g2 = Girl('王萌')
    b.girFriend = g2
    b.movie()
    
    
    一对多关系
    self.teach_list = [t1,t2,...]
    class School:
        def __init__(self,name):
            self.teach_list = []
        def zhaopin(self,teach):
            self.teach_list.append(teach)
        def shangke(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}在上课')
    lnh = School('测试')
    t1 = Teacher('赵老师')
    t2 = Teacher('刘老师')
    lnh.zhaopin(t1)
    lnh.zhaopin(t2)
    lnh.shangke()
    结果
    赵老师在上课
    刘老师在上课

    继承关系

    class Base:         #父类又叫基类又叫超类
        def chi(self):
            print('吃饭')
    class Foo(Base):    #子类又叫派生类,这个类继承了Base类,Foo类是对Base的一个扩展
        def he(self):
            print('喝水')
    f = Foo()
    f.chi()
    f.he()
    print(hash(Foo))    #默认类和创建的对象都是可哈希的
    print(hash(Foo()))
    结果
    吃饭
    喝水
    -9223371912599947772
    -9223371912597968945
    
    去掉可哈希
    __hash__ = None
    class Base:
        def chi(self):
            print('吃饭')
    class Foo(Base):
        __hash__ = None     # 当前类的对象不可哈希
        def he(self):
            print('喝水')
    f = Foo()
    f.chi()
    f.he()
    print(hash(Foo))    # 类名永远可哈希
    print(hash(Foo()))  # TypeError: unhashable type: 'Foo'

    类名相当于变量名

    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)
    结果
    吃鱼和 面包
    吃肉和 牛奶

    self:谁调用的就是谁,类型是根据调用方的对象来进行变换的
    super:表示的是父类

    特殊成员:
    __init__()  # 创建对象的时候初始化操作
    __call__()  # 对象()
    __getitem__()   # 对象[哈哈]
    __setitem__()   # 对象[哈哈] = 值
    __new__()   # 创建对象的时候.开辟内存
    __hash__()  # 可哈希 hash()

    __call__ 
    对象后面加括号,触发执行
    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
    class Foo:
        def __init__(self):
            pass
    
        def __call__(self, *args, **kwargs):
            print('__call__')
    
    obj = Foo()  # 执行 __init__
    obj()  # 执行 __call__
    结果
    __call__
    
    事例2
    class Foo:
        def __init__(self):                 # 初始化操作
            print('我是init,我是第二')
    
        def __new__(cls, *args, **kwargs):  # 创建,是真正的构造方法,可以开辟内存
            print('我是new,我是第一')
            return object.__new__(cls)
    
        def __call__(self, *args, **kwargs): # 对象()   
            print('我是对象call')
    
        def __getitem__(self, item):        # 对象[]
            print('item',item)
            print('我是getite')
    
        def __setitem__(self, key, value):  # 对象[key] = value
            print('key',key)
            print('value',value)
    Foo()
    f = Foo()          # 自动执行__init__()
    f()                # 调用__call__()
    print(callable(f)) # 对象()
    print(f['娃哈哈']) #自动调用__getitem__()
    f['']='刘丽'     #自动的调用__getitem__()
    结果
    我是new,我是第一
    我是init,我是第二
    我是new,我是第一
    我是init,我是第二
    我是对象call
    True
    item 娃哈哈
    我是getite
    None
    key 人
    value 刘丽
    
    
    事例3
    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item):
            print(self.__dict__[item])
    
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    f1=Foo('sb')
    f1['age']=18
    f1['age1']=19
    print(f1.__dict__)
    del f1.age1
    del f1['age']
    f1['name']='alex'
    print(f1.__dict__)
    结果
    {'name': 'sb', 'age': 18, 'age1': 19}
    del obj.key时,我执行
    del obj[key]时,我执行
    {'name': 'alex'}
    
    
    事例4
    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        #这个对象字符串的表示
        def __str__(self):  #返回该对象的字符串表示形式
            return f'{self.name},{self.age}'
        def __repr__(self):  #该对象的官方的字符串表示形式
            return f'{self.name},{self.age}'
    s = Person('bob','18')
    print(s)
    结果
    bob,18
    
    事例5
    class B:
        def __str__(self):
            return 'str : class B'
        def __repr__(self):
            return 'repr : class B'
    b = B()
    print('%s' % b)     #这个执行的是__str__函数方法
    print('%r' % b)     #这个执行的是__repr__函数方法
    结果
    str : class B 
    repr : class B
    
    
    __del__
    析构方法,当对象在内存中被释放时,自动触发执行
    注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
    class Foo:
    
        def __del__(self):
            print('执行我啦')
    
    f1=Foo()
    del f1
    print('------->')
    结果
    执行我啦
    ------->
  • 相关阅读:
    算法笔记_187:历届试题 网络寻路(Java)
    算法笔记_186:历届试题 高僧斗法(Java)
    算法笔记_185:历届试题 格子刷油漆(Java)
    Tomcat,JBoss与JBoss Web
    JBoss Web和Tomcat的区别
    tomcat与jboss等容器的区别
    dubbo
    ZooKeeper学习第一期---Zookeeper简单介绍
    Java GC系列
    Tomcat中JVM内存溢出及合理配置
  • 原文地址:https://www.cnblogs.com/wangm-0824/p/10199615.html
Copyright © 2011-2022 走看看