python-类与继承

类的继承

什么是继承?

继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类。python中,父类、子类(派生类)只有在继承的时候才会产生。

继承的特性:子类会继承父类所有的属性。

为什么要用继承?

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

对象的继承

  1. python中支持一个类同时继承多个父类(不推荐使用,当继承多个父类的时候,功能与功能之间会出现混乱。)

  2. 使用__bases__方法可以获取对象继承的类

    class A:
        def __init__(self,a):
            self.a =a
    
    class B:
        def __init__(self,b):
            self.b =b
    
    class C(A,B):
        pass
    
    print(C.__bases__)
    
    (<class '__main__.A'>, <class '__main__.B'>)
    
  3. 在python3中如果一个类没有继承任何类,则默认继承object类

  4. 在python2中如果一个类没有继承任何类,不会继承object类

对象查找属性的顺序

对象本身--->对象的类--->父类--->父类的父类,如果还没找到就会报错

class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):  # self = b
        print('Foo.f2')
        self.f1()  # b.f1() 


class Bar(Foo):
    def f1(self): # b.f1() 
        print('Bar.f1')


b = Bar()
b.f2()  # Foo.f2

Foo.f2
Bar.f1

类的派生

派生:子类中添加新的属性得过程,这个过程就叫做派生;注意的是,在添加新的属性同时也会继承父类所有的东西。

派生方法一

  1. 类似于函数调用

    class Animal:
        def __init__(self,height,weight):
            self.height = height
            self.weight = weight
    
        def jiao(self):
            print('jiao')
    
    class People(Animal):
        def __init__(self,height,weight,name,age):
            Animal.__init__(self,height,weight)  #这个其实就是函数调用,不要继承也能实现
            self.name = name
            self.age = age
            
        def read(self):
            print('read')
            
    

派生方法二

  1. super().__init__方法

    class Animal:
        def __init__(self,height,weight):
            self.height = height
            self.weight = weight
    
        def jiao(self):
            print('jiao')
    
    class People(Animal):
        def __init__(self,height,weight,name,age):
            super().__init__(self,height,weight)  # python3中里面不需要添加参数,但是python2 中需要添加super(People,self)
            self.name = name
            self.age = age
    
        def read(self):
            print('read')
    
    

类的组合

组合是用来解决类与类之间代码冗余的问题

class People:
    def __init__(self,name,gender):
        self.name = name
        self.gender = gender

class Students(People):
    def __init__(self,name,gender,id):
        super().__init__(name,gender)
        self.id = id

    def choose_course(self,course):
        print(f'{self.name}选择了{course.name}')


class Teachers(People):
    def __init__(self,name,gender,level):
        super().__init__(name,gender)
        self.level = level

    def score(self, student, course, score):
        print(f'{self.name}給学生{student.name}课程{course.name}打分{score}')


class Course():
    def __init__(self,name,price):
        self.name =name
        self.price = price

class Admin(People):
    def create_course(self,name,price):  # create_course = Course
        course = Course(name,price)
        print(f'{self.name}创建了课程{name}')
        return course


# 实例化学生
rayn = Students('rayn','male','01')
rose = Students('rose','fmale','02')

# 实例化老师
nick = Teachers('nick','male',1)
tank = Teachers('tank','fmale',2)

#实例化管理员
egon = Admin('egon','male')

# 实例化课程
python = egon.create_course('python','20000') #egon.create_course == egon.Course
linux = egon.create_course('linux','18000')

# print(python.__dict__)

rayn.choose_course(python)
rose.choose_course(linux)

nick.score(rayn,python,100)
tank.score(rose,linux,1)

菱形继承问题

类的分类

  1. 新式类

    继承了object的类以及该类的子类,都是新式类;python3中所有的类都是新式类。

  2. 经典类

    没有继承object的类以及该类的子类,都是经典类,只有python2中才有经典类。

菱形继承问题

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

  1. 经典类:深度优先
  2. 新式类:广度优先

我们也可以用print(类名.mro())来查看类的继承关系

类的多态与多态性

多态:

多态值的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)

多态性:

多态性是指具有不同功能的函数,可以使用相同的函数名;这样就可以用一个函数名调用不同内容的函数。

posted @ 2019-06-24 20:09  raynduan  阅读(280)  评论(0编辑  收藏  举报