类的继承

类的继承

什么是继承

  • 继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类
  • 继承的特性是:子类会遗传父类的属性或方法
  • 继承是类与类之间的关系

为什么用继承

  • 使用继承可以减少代码的冗余

如何用继承

class School: # 父类
    pass
class Student(School): # 子类
    pass
print(Student.__bases__)
print(School.__bases__)
# (<class '__main__.School'>,)
# (<class 'object'>,)

注意:

  • 在 python 3中如果一个类没有继承任何类,则默认继承 object 类。
  • 在 python 2中如果一个类没有继承任何类,不会继承 object 类。

继承与抽象

继承:子类继承父类,描述的是子类与父类之间的关系,是一种什么是什么的关系。

抽象:不具体,不清晰。将多个子类中相同的部分进行抽取,形成一个新类。

正确使用继承:

1:先抽象再继承。

2:继承一个已经现存的类,扩展或修改原始的功能。

继承的应用

# 在python中,一个子类可以同时继承多个父类
class OldboyPeople: # 父类
    school = 'oldboy'
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

class Student(OldboyPeople): # 子类
    def study(self):
        print('%s同学正在学习'%self.name)

class Teacher(OldboyPeople): # 子类
    def teaching(self):
        print('%s老师正在教书'%self.name)

stu = Student('zkim', 20, '男')
stu.study()
tea = Teacher('jason', 18, '男')
tea.teaching()
# zkim同学正在学习
# jason老师正在教书

属性查找

class A:
    text = 'from A'
    
class B(A):
	text = 'from B'

b = B()
b.text = 'from b'
print(b.text)
# from b

查找循序:对象本身—>所在的类—>父类—>父类的父类—>object

类的派生

派生是什么

  • 派生:子类中新定义的属性的这个过程叫做派生,并且需要记住子类在使用派生的属性时始终以自己的为准。
  • 派生的用法一:
class OldboyPeople:
    school = 'oldboy'
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

class Student(OldboyPeople):
    def __init__(self, name, age, gender, number):
        OldboyPeople.__init__(self, name, age, gender)
        self.number = number

stu = Student('zkim', 20, '男', 11)
print(stu.__dict__)
# {'name': 'zkim', 'age': 20, 'gender': '男', 'number': 11}
  • 派生的用法二(super):
    • 严格以来继承属性查找关系
    • super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系)
    • super().init(不用为self传值)
    • super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以简写为super()
class OldboyPeople:
    school = 'oldboy'

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

class Student(OldboyPeople):
    def __init__(self, name, age, gender, number):
        super().__init__(name, age, gender)
        # super(Student, self).__init__(name, age, gender)
        self.number = number

stu = Student('zkim', 20, '男', 11)
print(stu.__dict__)

# {'name': 'zkim', 'age': 20, 'gender': '男', 'number': 11}

  • 覆盖:覆盖也称之为重写 overrides,当子类出现了与父类名称完全一样的属性或方法。
  • 注意:当你继承一个现有的类,并且你覆盖了父类的 _init_ 方法时,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需的参数 。

类的组合

什么是组合

  • 组合:组合也是一种关系,描述两个对象之间是什么有什么的关系。就是将一个对象作为另一个对象的属性。

为什么用组合

  • 为了重用现有的代码
  • 组合相比较继承,耦合度更低了。

如何用组合

# 假设我们有个手机,那么不适用继承如何使用手机呢。
class Phone: # 手机
    def __init__(self,price,brand,model):
        self.price = price
        self.brand = brand
        self.model = model

    def call(self):
        print('正在呼叫...')

class Person: # 人
    def __init__(self,name,age,gender,phone):
        self.name = name
        self.age = age
        self.gender = gender
        self.phone = phone

phone = Phone(1600,'华为','荣耀play')
person = Person('zkim',21,'男',phone)
person.phone.call()

# 正在呼叫...

菱形继承

类的分类

  • 新式类:继承了object 的类以及该类的子类都是是新式类。python 3中所有的类都是新式类。
  • 经典类:没有继承 object 的类都是经典类。只有python 2中才有经典类。

菱形继承问题

当继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找方法有:

  • 经典类下:广度优先
class A:
    x = 1 # 最后找父类的父类 A

class B(A):
    x = 2 # 3.找父类 B

class C(A):
    x = 3 # 4.找父类 C

class D(A):
    x = 4 # 5.找父类 D

class E(B,C,D):
    x = 5 # 2.再找所在的类

e = E()
e.x = 6 # 1.先找对象本身
print(e.x)

# 6

posted @ 2020-05-22 10:52  光吃葡萄皮  阅读(486)  评论(0编辑  收藏  举报
回顶部