python面向对象03--关联关系

164 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天

关联关系

has a

has a :一个类中使用了另外一个自定义类(包含关系)

  • 来段示例代码
class Computer:
    pass
class Books:
	pass
class Sutend:
	pass
computer = Computer('mac','深灰色')
book = Book('百年孤独','作者')
stu = Student('mzmm403',computer,book)
print(stu)

image-20220424212630785.png

这里我们要了解一个概念:类型

大概可以组略的定义两种类型

  • 系统类型

int float str list dict set

  • 自定义类型

比如说这里的computer类,student类

所有类型的值都叫做对象

is a

继承关系

  • 为什么要继承这个关系呢?
class Studen:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def eat(self):
        print('{}正在吃饭'.format(self.name))
class Docter:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def eat(self):
        print('{}正在吃饭'.format(self.name))
class Teacher:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def eat(self):
        print('{}正在吃饭'.format(self.name))
  • 我们这式会发现一个很大的问题,每定义一个类,我们就要重复好多次的属性定义和相同的方法定义,那么这时候继承显得非常重要

那我们就可以引入一个概念:父类(基类)

#定义一个父类Person
class Person:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def eat(self):
        print('{}正在吃饭'.format(self.name))
#继承父类        
class Student(Person):
    pass
#继承父类
class Docter(Person):
    pass
#继承父类
class Teacher(Person):
    pass

image-20220424215551574.png

  • 在创建对应类的对象时我们都是逐级往上寻找的,如果自己有该属性就不会向上继续寻找

这里这种逻辑会出现一个缺点,那就是无法求同存异

#定义一个父类Person
class Person:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def eat(self):
        print('{}正在吃饭'.format(self.name))
#继承父类        
class Student(Person):
    def __init__(self,name,age,gender,clazz):
        super().__init__(name,age,gender)     #通过这种方法就可以实现求同存异
        self.clazz = clazz

正如上述的代码那样,我们这个时候再调用eat方法便会失效,其根本是因为父类的初始化已经失效了,因此我们可以用super去解决

super().__init__()
super(type,object).__init__()

以上两者的唯一区别在于后者在内存里多了一层判断,判断创建的对象是不是由该类来的

  • 小结
  1. 如果类中不定义__ init __,那么会调用父类的

  2. 如果继承父类的__ init __同时还想定义初始化,我们得在当前类里面声明super().__init __()

  3. 如果父类定义一个普通方法,那么在调用方法的时候遵循自下而上的原则(这样的方式就叫做重写)

ps:父类提供的方法不能满足子类的要求,我们在子类内部定义一个同名的方法,这样就叫做方法重写