面向对象---继承

一.继承

1.继承的概念:

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类(多个父类是python特有的)
父类又可称为基类或超类,新建的类称为派生类或子类

2.类的继承分为:单继承和多继承

class Parent1:pass
class Parent2:pass
class Children( Parent1):pass #单继承
class Children( Parent1,Parent2):pass #多继承

查看继承 base和bases   在python3中所有的类都集成object

print(Children.__base__) #<class '__main__.Parent1'>
print(Children.__base__) #<class '__main__.Parent1'>
print(Children.__bases__) #(<class '__main__.Parent1'>, <class '__main__.Parent2'>)
#查看继承,只查看父类,不管父类的父类。在python3中所有的类都集成object
print(Parent2.__bases__)  #(<class 'object'>,)
View Code

3.继承与抽象(先抽象再继承)

3.1抽象即抽取类似或者说比较像的部分。抽象最主要的作用是划分类别

猫类 : 吃eat 喝drink 睡sleep 爬树climb
# 狗类 : 吃eat 喝drink 睡sleep 看家watch
class Pet:
    def __init__(self,name,kind,food):
        self.name = name
        self.kind = kind
        self.food = food
    def eat(self):
        print('%s吃%s'%(self.name,self.food))
class Cat(Pet):
    def climb(self):      # 派生方法
        print('%s在爬树' % self.name)
class Dog(Pet):
    def watch(self):     # 派生方法
        print('%s在看家' % self.name)
tom = Cat('Tom','暹罗猫','猫粮')   #子类使用名字(方法和静态变量),如果在子类中没有,就使用父类的
View Code

print(tom.name) #子类使用名字(方法和静态变量),如果在子类中没有,就使用父类的.此时父类中init中的self就是tom
实例化这个类
# 创建一个空对象
# 执行__init__方法:子类没有用父类的

3.2父类和子类拥有同名的方法时,子类的对象只会调用子类的 

如果想要调用父类的方法,需要 父类名.方法名(self,其他参数)

子类中有自己的属性如sex,kind。在子类的init中再调父类的init

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name # 对象属性 实例属性
        self.aggr=aggr
        self.hp = hp
class Person(Animal):
    def __init__(self,name,sex,aggr,hp):
        self.sex= sex # 派生属性
        Animal.__init__(self,name,aggr,hp)
    def attack(self,dog):
        print('%s打了%s'%(self.name,dog.name))
        dog.hp -= self.aggr
class Dog(Animal):
    def __init__(self,name,kind,aggr,hp):
        self.kind= kind
        Animal.__init__(self,name,aggr,hp)
    def bite(self,person):
        print('%s咬了%s'%(self.name,person.name))
        person.hp -= self.aggr
hei = Dog('小黑','teddy',260,10000)
alex = Person('alex','female',1,250)
View Code

4.super关键字 只存在python3中

单继承中 super会寻找父类
且在使用super调用父类方法的时候不需要再传self参数
# super().__init__(name,aggr,hp) 等于 super(Person,self).__init__(name,aggr,hp)
class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr=aggr
        self.hp = hp
    def eat(self):
        print("在Animal中")
class Person(Animal):
    def __init__(self,name,sex,aggr,hp):
        self.sex= sex
        # Animal.__init__(self,name,aggr,hp)
        super().__init__(name,aggr,hp)
    def eat(self):
        print("在Person中")
        #Animal.eat(self)  #同时用父类中的方法
        #super().eat()
alex=Person('alex','female',1,250)
#只用父类中的方法
# Animal.eat(alex)
# super(Person,alex).eat()
View Code

5.单继承问题。属性的引用,会先从子类中寻找,子类中不存在,就去父类中找,直到最顶级的父类

不要发生循环继承
依赖倒置原则 :高层模块不应该依赖低层模块
class A:
    def wahaha(self):print('in A')
class B(A):
    def wahaha(self):print('in B')
class C(B):
    def wahaha(self):print('in C')
class D(C):pass
d = D()
d.wahaha()  #in C
View Code

6.多继承问题:属性的引用,会先从子类中寻找,子类中不存在。会根据继承的顺序去用执行

class A:pass
    # def qqxing(self):
    #     print('in A')
class B:
    def qqxing(self):
        print('in B')
class C:
    def qqxing(self):
        print('in C')
class D(B,A,C):
    pass
d = D()
d.qqxing()
View Code

砖石继承问题

1.B和C继承A,D继承B和C.print(F.mro()) 查看继承顺序

class A:
    def display(self):
        print('in A')
class B(A):
    def display(self):
        print('in B')
class C(A):
    def display(self):
        print('in C')
class D(B,C):
    def display(self):
        print('in D')
d=D()
d.display()  #D中不存在这个方法的话,就去B中找,B中不存在就去C中找,仍不存在就去A中找
print(D.mro()) #<__main__.D'>, <__main__.B'>, <_main__.C'>, <__main__.A'>, <class 'object'>]
View Code

2.B和C继承A,D继承B,E继承C,F继承D,E

#查找顺序:1.F 2.D 3.B 4.E 5.C 6.A

3.super在单继承和多继承中

单继承找父类

class A:
    def display(self):
        print('in A')
class B(A):
    def display(self):
        super().display()  #在单继承中找父类
        print('in B')
class C(A):
    def display(self):
        print('in C')
class D(B):pass
d=D()
d.display()  #in A in B
View Code

super在多继承 根据mro(广度优先)顺序的


class A:
    def display(self):
        print('in A')
class B(A):
    def display(self):
        super().display()
        print('in B')
class C(A):
    def display(self):
        print('in C')
class D(B,C):pass
d=D()
d.display()  #in C in B
View Code

 

继承问题总结

1.python3中的所有类 都默认继承object。super只存在python中
2.查看继承的顺序D.mro()
3.新式类:如果一个类 继承了object 这个类就被称为新式类
经典类:没有继承object类 就被称为经典类 python2
4.深度优先 广度优先 都是一种遍历算法,把这个图中所有的项都走一遍,且不会重复
5.经典类和新式类的区别:
经典类 遵循 深度优先算法 且没有mro方法 python2
新式类 继承object 遵循 广度优先算法 有mro方法 python3
在python中如果把经典类变成新式类,在最顶级父类类名加上(obj)
6.super:单继承中 super就是找父类
多继承 super寻找的轨迹是根据mro(广度优先)顺序的
7.继承的作用:
减少代码的重用
提高代码可读性
规范编程模式
8.名词
抽象:抽象即抽取类似或者说比较像的部分。是一个从具题到抽象的过程。
继承:子类继承了父类的方法和属性
派生:子类在父类方法和属性的基础上产生了新的方法和属性

 

 
 
 
 
posted @ 2018-03-08 22:32  JERD  阅读(234)  评论(0编辑  收藏  举报