面向对象——继承与派生
一 继承
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())