今日内容大纲
01昨日内容回顾
02作业讲解
03继承
继承
面向对象三大特征:继承,封装,多态
在OOP(Object Oriented Programming)程序设计中,当我们定义一个class的时候,可以从某个现有的class 继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
class Animal: def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age def eat(self): print('都会吃。。。') class Person(Animal): pass
p1=Person('alex','male',20)
p2=Animal('jinxing','male',18)
p1.eat() #子类以及子类实例化的对象可以访问父类的任何方法和变量
print(p1.name) #结果是:alex
Person.eat(11) #类名可以访问父类的所有内容
继承有什么好处?最大的好处是子类获得了父类的全部属性及功能。上述例子中Person继承了Animal,则Person中就可以直接使用Animal中的eat方法
在实例化一个Person的时候,子类继承了父类的构造函数,就需要提供父类三个属性变量name,sex和age
继承还可以一级一级的继承
问题来了:子类中有一个eat方法,父类中也有一个eat方法,那么在实例化对象之后调用eat方法到底是子类中的还是父类中的呢?我想既要执行子类的方法,又要执行父类的方法,该怎么做?
上节课讲的查询顺序我们可以知道,实例化一个Person对象的时候,用那个实例化出来的对象通过.来调用时,会先从子类中查找eat方法,子类中没有再从父类查找
代码如下:
class Animal: def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age def eat(self): print('都会吃。。。') class Person(Animal): def eat(self): #1.Animal.eat(self) #2.super().eat() print('人吃东西...') p1 = Person('jiang','male',20) p1.eat()
有两种方法可以解决,第一种是在子类的eat方法中添加Animal.eat(self).这时就会先调用父类的eat方法
第二种是在子类的eat方法中添加super().eat()。功能一样但是一般用这种方法
问题二:动物有些属是特有的,该如何添加这些特有的属性?
代码如下:
class Animal: def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age def eat(self): print('都能吃') def drink(self): print('都能喝') class Dog(Animal): def hit(self): print('狗会咬人') class Bird(Animal): def __init__(self,name,sex,age,wing):#self接收的是b1对象 #Animal.__init__(self,name,sex,age) #一般不用这种方法 super(Bird,self).__init__(name,sex,age)#super().__init__(name,sex,age) self.wing=wing def miao(self): print('嗷嗷叫') def eat(self): #super().eat() #Animal.eat(self) print('%s会吃...'%self.name) #既要执行子类的方法,又要执行父类的方法 #1.#Animal.__init__(self,name,sex,age) #2.super().__init__(name,sex,age) b1 = Bird('鹦鹉','公',10,'绿翅膀')
继承的进阶:
#类:经典类,新式类
#新式类:凡是继承object类都是新式类
#python3中,所有的类都是新式类
#因为python3中的类都默认继承object
#经典类:不继承object类都是经典类(python3中不存在)
#python2中既有新式类,又有经典类,所有的类默认都不继承object,所有的类默认都是经典类
#单继承:新式类,经典类查询顺序一样
#多继承:
#新式类:遵循广度优先
#经典类:遵循深度优先
#多继承的新式类 广度优先 class A: def func(self): print('IN A') class B(A): pass #def func(self): #print('IN B') class C(A): pass #def func(self): #print('IN C') class D(B): pass #def func(self): #print('IN D') class E(C): #pass def func(self): print('IN E') class F(D,E,C): pass f1 = F() f1.func() print(F.mro()) #可以查询类的继承顺序
广度优先:F->D->B->E->C->A
#多继承的经典类 深度优先:一条路走到底