面向对象之继承

面向对象三大特性之继承

一.继承

1.什么是继承

  继承是一种关系,必须存在两个对象才可能产生这一种关系。在程序中继承指的是类与类之间的关系。新建的类可以继承1个或者多个父类,父类又被称为基类,超类,新建的类可以被称为子类或派生类。

2.为什么要使用继承

在程序中,通过继承可以直接使用父类已有的代码,可以减少类与类之间的代码冗余。

3.怎么使用继承

#单继承
class
Father: #定义父类 a=10 class Son( 父类的名称 Father): #定义子类 pass son=Son() print(son.a) >>>: 10

#多继承
class Father1:  #定义父类
    a=10
class Father2:  #定义父类
    b=10
class Son( 父类的名称 Father1,Father2):#python支持多继承,用逗号分隔开多个继承的类

son=Son()

print(son.a)

print(son.b)
>>>:
10
10
 

4.查看继承

print(Son.__bases__) #使用__bases__可以查看Son类所继承的所有父类
>>>:
(<class '__main__.Father1'>, <class '__main__.Father2'>)

二.继承与抽象(先抽象后继承)

继承是类与类之间的一种关系,抽象是指抽取多个类中相同的部分形成一个类。

抽象分成两个层次: 

1.将奥巴马和梅西这俩对象比较像的部分抽取成类; 

2.将人,猪,狗这三个类比较像的部分抽取成父类。

抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)

继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。

三.派生

1.什么是派生

派生指的是子类继承某个父类,但是这个子类拥有自己独特的属性或者技能,那么该子类就称之为派生类,也就是说子类中出现了新内容那么他就是一个派生类。

注意:派生类一定是子类,但是子类不一定是一个派生类。

#普通子类
class
Person: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def sayHI(self): print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex)) class Test(Person): pass #此时Test不能被称为派生类,它只是一个子类,因为Test类没有任何独特的内容,它的内容与父类完全一致。
#派生类
class Student(Person):# class Test(Person):
# pass

def __init__(self,name,age,sex,number):
self.name = name
self.age = age
self.sex = sex
self.number = number

# 上课
def up_class(self):
print("%s 正在上课.....")
#此时Student类是一个派生类,因为它比父类Person多了一个方法和一个number属性

在上述派生类的代码中,我们发现我们重新写了一个初始化函数将参数自动传进去,那么不就又回到了没有继承之前的写法了吗,有没有什么方法能让子类可以继续使用父类的特征,然后在添加一个可以自动传参的特征呢?下面我们就来介绍一些这个方法。

四.子类访问父类的方法

1.指名道姓的访问父类的方法

class Person:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

class Student(Person):
    def __init__(self,name,age,sex,number):
        Person.__init__(self,name,age,sex)

        self.number=number

stu1=Student("egon",18,"man","007")
print(stu1.name,stu1.age,stu1.sex,stu1.number)

>>>:
egon 18 man 007

#看上面的代码,在子类的初始化函数中,直接调用父类名.__init__(self,.....)的形式能直接调用定义在父类中的初始化函数,从而达到了可以访问父类属性的目的。

2.使用super()函数的方式访问父类

class Person:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex


class Student(Person):
    def __init__(self,name,age,sex,number):
        super().__init__(name,age,sex)   


        #python2中的用法,但是python3也兼容这种形式
        # super(Student, self).__init__(name,age,sex) 

        self.number=number

stu1=Student("egon",18,"man","007")
print(stu1.name,stu1.age,stu1.sex,stu1.number)

>>>:
egon 18 man 007

补充知识:super()函数对类中的方法也有相同的作用

class Person:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def sayHi(self):
        print("BYE BYE")

class Student(Person):
    def __init__(self,name,age,sex,number):
        super().__init__(name,age,sex)
        self.number=number

    def sayHi(self):
        super().sayHi()
        print("see you tomorrow")

stu1=Student("egon",18,"man","007")
stu1.sayHi()

>>>:
BYE BYE
see you tomorrow

#当我们需要在子类继承父类的方法中添加新东西中,可以使用super函数的方法添加
super()为子类继承的父类方法添加功能

 五.继承关系下的属性查找问题   (子类出现了与父类重复的名字 称之为覆盖)

由于一个子类可以继承多个父类,所以有可能会出现菱形继承的形式,所以继承关系下的属性查找也分为两类

1.继承多父类的继承关系下的非菱形继承下的属性查找规则:深度优先

class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()

顺序为:F->D->B->E->C->A

2.继承多个父类的继承关系下菱形继承下的属性查找规则:深度优先+广度优先

class S:
    a = 100

class A(S):
    # a = 1
    pass
class B(S):
    # a = 2
    pass
class C(S):
    # a = 3
    pass
class D(A):
    # a = 4
    pass
class E(B):
    # a = 5
    pass
class F(C):
    # a = 6
    pass
class G(D,E,F):
    pass


g1 = G()
print(g1.a)
print(G.mro())

"""
s
a,b,c
d,e,f
g
"""
g->d->a->e->b->f->c->s

六.经典类与新式类

1.只有在python2中才分新式类和经典类,python3中统一都是新式类
2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
3.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类

posted on 2018-12-14 16:19  黑粥  阅读(317)  评论(0编辑  收藏  举报

导航