python--类与类之间的关系,(魔术方法)特殊成员方法

1.依赖关系

类与类之间存在这几种关系:1.依赖关系 2.关联关系 3.组合关系 4.聚合关系 5.继承关系 6.实现关系

 我们来设置下面两个场景 玩电脑和打僵尸

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)



# 写一个植物大战僵尸
# 1. 植物
#       打僵尸. 僵尸掉血
# 2. 僵尸
#       吃植物. 植物掉血

class Plant:
    def __init__(self, name, hp, ad): # 200
        self.name = name
        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, name, hp, ad): # 1000  800
        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("歪脖子豌豆", 10, 20)
# 僵尸
js = JiangShi("铁桶僵尸", 200, 1)
wd.attack(js)
wd.attack(js)
wd.attack(js)
wd.attack(js)
wd.attack(js)

js.attack(wd)
js.attack(wd)
js.attack(wd)
js.attack(wd)

  

 

 

2.关联关系,组合关系,聚合关系

这三个在代码上写法是一样的,但是,从含义上是不一样的

1.关联关系:两种事物必须是互相关联的.但是在某种情况下是可以更改和更换的

2.聚合关系.属于关联关系中的一种特例.侧重点是xxx和xxx聚合成xxx.各自有各自的声明周期.比如电脑,电脑有cpu,硬盘,内存等等.电脑坏了,cpu还是好的,还是完整的个体.

3.组合关系.属于关联关系中的一中特例.写法上差不多.组合关系比聚合还要紧密,比如人的大脑,心脏,各个器官,这个器官组合成一个人.这是人如果挂了.其他的东西也就失效了

我们举个例子,男人关联着女朋友,女人关联着男朋友.这种关系可以是互相的

class Boy:

    def __init__(self, name,  girlFriend=None):
        # 在初始化的时候可以给一个对象的属性设置成另一个类的对象
        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()

# 给小名介绍一个女朋友 小红
b.girlFriend = g
b.chi()

g2 = Girl("小红")
b.girlFriend = g2 # 换了个女朋友
b.chi()


class School:

    def __init__(self, name):
        self.teach_list = [] # 这里要装多个老师
        self.name = name

    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("王老师")
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()

1.一对一关系 只有一个女朋友  2.一对多关系  一个学校,一堆老师

 

 

 

3.继承关系,self

self:谁调用的就是谁.类型是根据调用方的对象来进行变换的,self在访问方法的顺序,永远先找自己的.自己找不到再找父类的

super:表示的是父类

 

 

 

4.类中的特殊成员

 

__init__ :      构造函数,在生成对象时调用,类名()会自动执行
__del__ :       析构函数,释放对象时使用
__repr__ :      打印,转换为解释器读取的形式
__setitem__ :   按照索引赋值
__getitem__:    按照索引获取值
__len__:        获得长度
__cmp__:        比较运算,对象比较
__call__:       调用
__add__:        加运算
__sub__:        减运算
__mul__:        乘运算
__div__:        除运算
__mod__:        求余运算
__pow__:        幂
__call__        对象()会自动执行
__getitem__     对象[key]会自动执行
__setitem__     [key]=value会自动执行
__delitem__      del对象[key]会自动执行
__enter__  和__exit__      with对象as变量会自动执行
__str__          打印对象的时候会自动执行 
__hash__  == None 对象就不可哈希了
__new__          开辟内存
__iter__         iter(对象)

 

__init__()就是一个特殊的成员.这些方法在特殊的场景的时候会被自动执行

类名()会自动执行__init__()
def __init__(self): # 初始化操作
       print("我是init,  我是老二")
       print("初始化操作. 在创建对象的时候自动调用这个方法")

 def __new__(cls, *args, **kwargs): # 创建, 它是真正的构造方法, 可以开辟内存
     print("我是new. 我是老大")
          return object.__new__(cls)

 
对象()会自动执行__call__()
def __call__(self, *args, **kwargs):
        print("我是对象()")
对象[key]会自动执行__getitem__()
 # 对象[]
 def __getitem__(self, item):
      print("item=",item)
      print("你执行了__getitem__")
      return "哈哈"
del 对象[key]会自动执行__delitem__()
del lst[1]
     def __delitem__(self, key):
          print("key=", key)
with对象as变量 会自动执行__enter__和__exit__
# with 对象:
def __enter__(self):
   print("我是enter")

# with 对象: 代码执行完毕. 最后执行这里
def __exit__(self, exc_type, exc_val, exc_tb):
   print("我叫exit")
打印对象的时候会自动执行__str__
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", "男", "三年二班", "31")
print(s)
干掉可哈希__hash__ == None 对象就不可哈希了

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

 

posted @ 2018-12-19 20:54  robertx  阅读(351)  评论(0编辑  收藏  举报