欢迎光临
我们一起进阶

Python面向对象——类与类之间的关系

扫码或搜索:沉默王二
发送 290992
即可立即永久解锁本站全部文章

上节讲完了静态方法、类方法,这节就开始讲:

类与类之间的关系

  依赖关系. 关联关系. 组合关系. 聚合关系. 继承关系. 实现关系
下面请听一一我分说:
一. 依赖关系

执行某个动作的时候, 需要借助某个东西, 但这个东西不是绝对的, 此时关系是最轻的, 随时可以更换另外一种东西执行动作, 通过参数的传递把另外一个类的对象传递进来。

代码如下:

class Elephant:

    def __init__(self, name):
        self.name = name

    def open(self, ref):
        print('冰箱开门吧')
        ref.open_door()

    def close(self, ref):
        print('冰箱关门吧')
        ref.close_door()

    def get_in(self):
        print('进冰箱装自己')

class Refrigerator:

    def open_door(self):
        print('冰箱默默地打开了自己的门')

    def close_door(self):
        print('冰箱默默地关上了自己的门')

class GaoYaGuo:
    def open_door(self):
        print('高压锅打开了自己的盖子')

    def close_door(self):
        print('高压锅关上了自己的盖子')

e = Elephant('小象')
ref1 = Refrigerator()
guo = GaoYaGuo()
#大象进冰箱
e.open(ref1)
e.get_in()
e.close(ref1)
#大象进了高压锅
e.open(guo)
e.get_in()
e.close(guo)

# 大象与冰箱和高压锅是依赖关系,联系并不紧密,可以更改对象

二. 关联关系. 组合关系. 聚合关系(对象里面埋对象) 这三个在代码写法上是一样的, 但是含义是不一样的

  1. 关联关系两种事物必须是互相关联的, 但在某些特殊情况下是可以更改和更换的
    一对一关系: 在初始化的时候给一个对象的属性设置成另一个类的对象, 把属性和对象联系起来
    一对多关系:

  2. 聚合关系
    属于关联关系的一个特例, 侧重点是xxx和xxx聚合成xxx, 各有各的生命周期,

  3. 组合关系
    属于关联关系中的一个特例, 组合关系比聚合关系要紧密

class Boy:
    def __init__(self, name, character, girlFriend=None):
        self.name = name
        self.character = character
        self.girlFriend = girlFriend

    def meet(self, girl):       # 给girlFriend传值
        self.girlFriend = girl

    def eat(self):
        if self.girlFriend:     # if True  如果有girlFriend
            print('%s和%s随便吃' % (self.name, self.girlFriend.name))
        else:                   # 如果没有girlFriend
            print('单身狗不用吃')

class Girl:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print('%s在吃饭' % self.name)

girl = Girl('白骨精')

alex = Boy('金角大王', '娘')

alex.eat()
alex.meet(girl)
alex.eat()

girl.eat()
alex.girlFriend.eat()

#一个对多个

class School:
    # def __init__(self, name, address, tel, teach_list=[]):  #teach_list写在这里是默认值参数,可以共用,如果该参数是可以修改的,一旦内容改变,不同对象共用相同内容
    def __init__(self, name, address, tel):
        self.name = name
        self.address = address
        self.tel = tel
        self.__teach_list = []  #每一个对象(学校)都会有一个teach_list,默认是空  # 教师信息不对外展示,私有属性

    def hire(self, teacher):
        self.__teach_list.append(teacher)

    def display(self):
        for el in self.__teach_list:
            print(el.name, el.hobby)

class Teacher:
    def __init__(self, name, gender, salary, hobby, school):
        self.name = name
        self.gender = gender
        self.salary = salary
        self.hobby = hobby
        self.school = school

oldboy_bj = School("北京老男孩", "美丽富饶的沙河", "10086")
oldboy_sh = School("北京老男孩上海分校", "上海浦东", "10010")
oldboy_sz = School("北京老男孩深圳分校(骑士计划)", "南山区", "10000")


t1 = Teacher("配齐", "男", 200000, "上课", oldboy_bj)
t2 = Teacher("太白", "男", 150000, "开车", oldboy_bj)
t3 = Teacher("Eggon", "男", 123456, "钻研技术", oldboy_sh)
t4 = Teacher("高鑫", "女", 45678, "相夫教子", oldboy_sz)
t5 = Teacher("日天", "男", 666, "看天", oldboy_sz)

print(t3.school.name, t3.school.address)  # 找到老师所在的学校名称和地址

oldboy_bj.hire(t1)
oldboy_bj.hire(t2)
oldboy_bj.display()

oldboy_sh.hire(t3)

oldboy_sz.hire(t4)
oldboy_sz.hire(t5)

oldboy_sz.display()

三. 继承关系

子类在不影响父类的程序运行的基础上对父类进行的扩充和扩展, 这里, 把父类成为超类或者基类, 子类被称为派生类

类名和对象默认是可以作为字典的key的, 可以hash, 即字典的key可以是对象或者类self: 谁调用的就是谁, 类型是根据调用方对象来变换的, 访问顺序: 永远是先找自己的, 自己的找不到再找父类的

四. 类中的特殊成员

(init) (尽量了解)
init()
new()
getitem() obj[xxx]
setitem() obj[xxx] = xxxx
delitem() del obj[xxx]
call() obj()
str() print(obj) 返回这个对象的字符串表示形式
enter()
exit() with

类名和对象是否可以作为key

# 可哈希. 内部是否哈希算法 __hash__

class Foo(object): # 所有的类都会默认继承object
    def __init__(self):
        pass
    def func(self):
        pass
    __hash__ = None  # 默认的类和对象都是可哈希的,如果加了__hash__ = None,则变为不可哈希

dic = {}
dic[Foo] = "123456" # 类名是可哈希的。
dic[Foo()] = "刘伟" # 类中是否包含__hash__
print(dic)

View Code

class Foo:
    def __init__(self):
        print("我是初始化")

    def __call__(self, *args, **kwargs):
        print("我是靠")

    def __getitem__(self, item):
        print("我是getitem", item)
        return "大胖小子"
    def __setitem__(self, key, value):
        print(key, value)

    def __delitem__(self, key):
        print(key)

    def __enter__(self):
        print("我是进入")
        return "周润发"
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("我是出来")


# 类名()  __init__() 构造方法
obj = Foo()

# 对象() __call__()
obj() # python特有的.

# 对象[xxx] 从对象中获取数据  默认执行__getitem__()
print(obj['小明'])

# 对象[xxx] = ,.... 默认执行__setitem__()
obj["汪峰"] = "章子怡"

# del obj[key] 默认执行__delitem__()
# del obj['马化腾']



# dic = {"name":'汪峰', 'age':18}
# print(dic['name'])
#
# with obj as xx:       # __enter__()    __exit__()
#     print(xx)
#     print("你好. 我叫周润发")

View Code

class Boy(object):
    def __init__(self, name, address, phone):
        self.name = name
        self.address = address
        self.phone = phone

    def __str__(self):     #打印对象时显示对象内容 而不是显示类中的对象
        return "name:%s, address:%s phone:%s" % (self.name, self.address, self.phone)

    def __new__(cls, *args, **kwargs):
        print("新概念")
        return object.__new__(cls) # 这句话才是创建对象.


b = Boy("alex",  "北京沙河", "10086")
print(b)

View Code getitem用法示例

# __getitem__的用法
#方法一:

class DataBase:
    '''Python 3 中的类'''

    def __init__(self, id, address):
        '''初始化方法'''
        self.id = id
        self.address = address
        self.d = {self.id: 1,
                  self.address: "192.168.1.1",
                  }

    def __getitem__(self, key):
        # return self.__dict__.get(key, "100")
        return self.d.get(key, "default")


data = DataBase(1, "192.168.2.11")
print(data["hi"])
print(data[data.id])

# 方法二

class DataBase:
    '''Python 3 中的类'''

    def __init__(self, id, address):
        '''初始化方法'''
        self.id = id
        self.address = address

    def __getitem__(self, key):
        return self.__dict__.get(key, "100")


data = DataBase(1, "192.168.2.11")
print(data["hi"])
print(data["id"])

# 方法三

class STgetitem:

    def __init__(self, text):
        self.text = text

    def __getitem__(self, index):
        result = self.text[index].upper()
        return result


p = STgetitem("黄哥Python")
print(p[0])
print("------------------------")
for char in p:
    print(char)

# 示例引用自https://zhuanlan.zhihu.com/p/27661382

View Code getitem与setitem用法示例

class SetAndGet:
    __dv__ = {}  # Dictionary Values
    def __init__(self, dv={}):
        self.__dv__ = dv

    def __getitem__(self, key):
        return self.__dv__.get(key, None)

    def __setitem__(self, key, value):
        self.__dv__[key] = value
        print('我是setitem')

obj = SetAndGet()
obj['name'] = 'alex'
print(obj.__dv__)
print(obj['name'])

如果属性查找(attribute lookup)在实例以及对应的类中(通过dict)失败, 那么会调用到类的getattr函数, 如果没有定义这个函数,那么抛出AttributeError异常

五. 创建对象的步骤
  1. 加载类(给类创建一个名称空间, 存放类变量, 此时不创建类对象, 也能使用类变量)

  2. 创建对象: 开辟内存(new), 初始化(init) (先找类, 根据类名来开辟内存执行类中的newinit, 返回对象)

  3. 操作对象

赞(0) 打赏
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

小白学堂,学的不止是技术,更是前程

关于我们免责声明

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏