主要内容:

1.继承

2.新式类与经典类

3.多继承的优先查询 

一.继承

定义一个类,class Dog(Animal)  其中括号里面的Animal是父类/基类/超类,括号外面的Dog是子类/派生类. 

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

当我们在定义多个类的时候,发现要用到相同的方法或变量,如果每个类都要写相同的方法和变量,那么代码就会重复,为了减少代码,可以用继承来解决. 

# encoding:utf-8
# 如果是用的python2,python2默认使用ascii码,先再第一行写上encoding:utf-8 ;
# python3默认使用的是utf-8

组合:让一个类对象与另一个类的对象发生关系
继承:让类与类发生关系

面向对象的三大特性: 继承 多态 封装
面向对象为什么要有继承?继承的好处是什么?
      a, 提高了代码的复用性
      b:提高了代码的维护性
      c:让类与类之间产生了关系,是多态的前提
# 子类以及子类实例化的对象 可以访问父类的任何方法或变量.
# 类名可以访问父类所有内容
# 子类实例化的对象也可以访问父类所有内容
# 父类不能访问子类的东西
#这几个类用到了相同的方法和变量,为了提高代码的复用性,引入继承的思想
class Animal:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age

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

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

class Dog:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
class Animal:
    breath = '呼吸'

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

    def eat(self):
        print(self)
        print('动物都需要进食....')


class Person(Animal):  # 括号里面的 父类,基类,超类   括号外面的 子类,派生类.
    pass


class Cat:
    pass


class Dog:
    pass


p1 = Person('alex', 'laddyboy', 1000)
print(p1.__dict__)  #{'name': 'alex', 'sex': 'laddyboy', 'age': 1000}

# 初识继承:
# 子类以及子类实例化的对象 可以访问父类的任何方法或变量.
# 类名可以访问父类所有内容
print(Person.breath)   #呼吸
Person.eat(111)   #111
                  #动物都需要进食....
# 子类实例化的对象也可以访问父类所有内容
print(p1.breath)  #呼吸
print(p1)     #<__main__.Person object at 0x0000006ECD9A7C88>
p1.eat()    #<__main__.Person object at 0x0000006ECD9A7C88>
            #动物都需要进食....

 查询顺序:子类的对象空间==>子类空间==>父类空间

python 中文姓名识别 python 名字_子类

 

只执行父类的方法:子类中不要定义与父类同名的方法
只执行子类的方法:在子类创建这个方法.

既要执行子类的方法,又要执行父类的方法?
有两种解决方法.
 1,Animal.__init__(self, 参数)
     2,super().__init__(参数)

 

class Animal:
    def __init__(self,name):
        self.name=name

    # def eat(self):
    #     print("会")

    def eat(self):
        print("%s会吃" %self.name)

    def drink(self):
        print("%s会喝" %self.name)

class Cat(Animal):
    def tian_zhua_zi(self):
        print("%s会舔爪子" %self.name)

class Dog(Animal):
    def kan_jia(self):
        print("%s会看家" %self.name)

class Chicken(Animal):
    def xia_dan(self):
        print("%s会下蛋" %self.name)


class Bird(Animal):
    def __init__(self,name,wing):     #self=Bird的实例化对象b,  name="鹦鹉",  wing="绿翅膀"
        #Animal.__init__(self,name)    #类名.函数+(),,相当于函数的调用,()里面装的是实参,把self,name当做实参传进来
                     # (self现在是指Bird的对象b,也就是个空间地址),然后执行函数,父类的函数对name进行封装,函数执行完毕,
                     # 执行下一步,self.wing=wing,是Bird自身对对象的属性进行封装.
        super().__init__(name)#super(Bird,self).__init__(name)  用super()直接把想要的父类的参数拿过来,然后封装自己的参数
        self.wing=wing
        print(name,wing)

    def eat(self):
        super().eat()
        print("%s会吃小虫子" % self.name)


# c=Cat()     #父类中没有__init__方法,实例化一个子类的对象,子类的对象调用父类的方法,也会执行父类方法中的内容
# c.eat()

# c=Cat("猫")
# c.eat()
# c.drink()
# c.tian_zhua_zi()
#
# d=Dog("狗")
# d.eat()
# d.drink()
# d.kan_jia()
#
# j=Chicken("鸡")
# j.eat()
# j.drink()
# j.xia_dan()

二.新式类与经典类

继承: 单继承,多继承.

  单继承:只继承一个父类
          class A(B):
              pass
多继承:继承两个及两个以上的父类
          class A(B,C):
              pass
  
类: 经典类, 新式类

 新式类: 凡是继承object类都是新式类.
          python3x 所有的类都是新式类,因为python3x中的类都默认继承object.

经典类: 不继承object类都是经典类
          python2x:(既有新式类,又有经典类) 所有的类默认都不继承object类,所有的类默认都是经典类.你可以让其继承object.

 三.多继承的优先查询 

1.单继承: 新式类,经典类查询顺序一样.
2.多继承:
     新式类: 遵循广度优先.
     经典类: 遵循深度优先.

3.多继承的新式类  
  
广度优先 : 一条路走到倒数第二级,判断,如果其他路能走到终点,则返回走另一条路.如果不能,则走到终点.

python 中文姓名识别 python 名字_python 中文姓名识别_02

4.多继承的经典类  

深度优先 : 一条路走到底.

5.查询类的继承顺序: 类名.mro()
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):
    pass
    # def func(self):
    #     print('IN F')

f1 = F()
print(F.mro())
#[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
6.多继承广度优先查询算法
#例子1

class H:
    pass


class G(H):
    pass


class F(H):
    pass


class E(G):
    pass


class D(F):
    pass


class C(E):
    pass


class B(D):
    pass


class A(B, C, D):
    pass


print(A.mro())

'''
首先找到A继承的三个类的深度继承顺序,放到一个列表中

B   [B,D,F,H]
C   [C,E,G,H]
D   [D,F,H]

每个列表的第一个元素为头部,其它位置元素都为尾部,从第一个列表的头部开始找,找其他列表中尾部是否含有
这个类名,如果没有,提取出来放到一个列表中,如果有,找下一个列表的头部,循环下去
只要提取来一个,我们就从第一个列表的头部接着重复上面的操作.

A   [A] [B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]   A #找到第一个列表的头A,其他列表尾部没有A,把A取出来,如果其他列表的头部有A则剔除
    []  [B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]   B
    []  [D,F,H]   [C,E,G,H] [D,F,H] [C,D]     C
    []  [D,F,H]   [E,G,H]   [D,F,H] [D]       D
    []  [F,H]     [E,G,H]   [F,H]   []        F 
    []  [H]       [E,G,H]   [H]     []        E #找到第一个列表的头部H,但是其他列表尾部有H,所以跳过这个列表,去下一个列表取头部
    []  [H]       [G,H]     [H]     []        G
    []  [H]       [H]       [H]     []        H
    []  []        []        []      [] 
lst = [A,B,C,D,F,E,G,H] 
'''
#例子2

class F:
    pass


class E:
    pass


class D:
    pass


class C(D, F):
    pass


class B(E, D):
    pass


class A(B, C):
    pass


print(A.mro())
'''
首先找到A继承的两个类的深度继承顺序
把B作为子类,找出B类的查询顺序

B   [B] [E] [D] [E,D]   B  
    []  [E] [D] [E,D]   E
    []  []  [D] [D]     D
    []  []  []  []
lst = [B,E,D]
把C作为子类,找出C类的查询顺序

C   [C] [D] [F] [D,F]   C
    []  [D] [F] [D,F]   D
    []  []  [F] [F]     F
    []  []  []  []       
lst = [C,D,F]

A   [A] [B,E,D] [C,D,F] [B,C]   A
    []  [B,E,D] [C,D,F] [B,C]   B 
    []  [E,D]   [C,D,F] [C]     E
    []  [D]     [C,D,F] [C]     C
    []  [D]     [D,F]   []      D
    []  []      [F]     []      F
    []  []      []      []
lSt = [A,B,E,C,D,F]    
'''