Fork me on GitHub

面向对象——继承与派生

一 继承

 1  我们这里所说的继承,不是我们日常生活中遗产的继承,是对于类来说的,他是我们创建新类的一种方式。我们把通过继承产生的类叫做子类,又叫派生类。

而父类又可称为基类或超类。

  特点:使用继承我们可以减少冗余的代码,同时通过继承产生的子类会继承父类中的一些特征与技能,也就是我们类中的变量与函数。

 二   类的使用:

我们之前说类是一系列对象的特征与技能的集合体,那么继承所说的是是类与类之间的关系,寻找这种关系我们同样需要先抽象类,也就是找出类与类相似的地方。

那么下面我们通过一个列子来更进一步说明继承到底是怎么回事:


继承
class Poeple:#####父类
school = 'oldboy'

def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
老师类,学生类:
class Teacher(Poeple):###子类1

school = 'oldboy'

def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def teaching(self):
        pass
    def work(self):
        pass
class Stedent(Poeple):####子类2
    def f1(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex  
def learn(self): pass obj1=Teacher('egon',18,'male') obj2=Stedent('alex',73,'female') print(obj1.name) print(obj2.name)
从上面这个程序我们可以看出:
class Stedent(Poeple)与class Teacher(Poeple)中存在相同的代码,如果这段代码比较长的话,就会造成我们代码的冗余,于是我们可以把这段代码单独拿出来,
做成一个父类,然后使用继承的方式,再将这段代码传给他的子类。他的子类在定义是类的名字后面加上(父类类名)就可以。

三 属性查找:

那么对于类的属性查找我们我们依然按照:先找对象自己本身——〉然后到所在子类中去找————〉最后到子类所属父类中去找:

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

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

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

b=Bar()
b.f2()
从上述代码我们可以看出,当我们调用Bar()执行到f1时,这个f1实际上父类与子类都有但是我们先到子类中去找,那么我们再调用f2这个时候只有父类中有中
那么我们就只能从父类找。

四  这里一个子类可以由多个父类继承而来,所以这种情况下我们应该怎么找呢:

属性顺序的查找我们可以分为两种:我们在python3中,可以利用print(类名.mro())来查看属性的查找顺序。

经典类与新式类:

1.只有在python2中才分新式类和经典类,python3中统一都是新式类
2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
3.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。

 

  1当类是经典类:深度优先,(没有继承object以及其子类的是经典类)

  2当类是新式类时:广度优先(继承了object及其子类的叫新式类。)

五  派生:

 我们上面讲了继承, 有时候我们子类需要在继承的基础上再添加自己的功能,那么这个时候就用到了派生,派生就是在不影响父类的基础上对子类进行功能的增加。

那么如果存在子类在定义新的属性时,与父类中的属性同名,那么子类在调用时以子类自己的为准

那么我们在子类中重用父类的功能:

第一种方式就是指名道姓:比如我们要用父类OldboyPeople中的tell_info功能,那么我们必须通过:OldboyPeople.tell_info来调用。可以不依赖于继承。

第二种方式:

使用super().__init__()####super后面是不需要传值的,他的功能就是调用父类的——init——函数,必须严格依赖于继承。

重用父类的功能,必须指向父类的类名,这样才能在父类与子类存在相同函数的情况下引用父类中的函数。
class OldboyPeople:
    school = 'oldboy'

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

    def tell_info(self):
        print("""
        ===========个人信息==========
        姓名:%s
        年龄:%s
        性别:%s
        """ %(self.name,self.age,self.sex))


class OldboyTeacher(OldboyPeople):
    #            tea1,'egon', 18, 'male', 9, 3.1
    def __init__(self, name, age, sex, level, salary):
        # self.name = name
        # self.age = age
        # self.sex = sex
        # OldboyPeople.__init__(self,name, age, sex)
        super().__init__(name,age,sex)

        self.level = level
        self.salary = salary

    def tell_info(self):
        # OldboyPeople.tell_info(self)
        super().tell_info()
        print("""
        等级:%s
        薪资:%s
        """ %(self.level,self.salary))

tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1)
# print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary)
tea1.tell_info()
print(tea1.tell_info())

 

posted @ 2018-04-12 15:10  道阻切长  阅读(238)  评论(3编辑  收藏  举报