继承:使程序的代码更加简练,提高了程序的可读型
实现继承格式:
class 子类名(父类名):
pass
继承了父类的非私有的属性
对于公有的属性和方法是可以在子类中访问的,但是私有的无法访问
1、子类继承父类的非私有属性和方法
2、如果子类和父类定义了一个相同的属性,先找子类的属性,再去找父类的属性
3、如果父类与子类有相同的方法,则任务子类重写了此方法(重写:override,覆盖)
单继承:
所有的类默认继承object
继承其父类的方式:class 子类(父类):
1、单继承

class Test:
    name = 'tang'
    age = '24'

class Test1(Test):
    def show(self):
        return '这里是调用Test类的name和age属性,name的值为:{},age的值为:{}'.format(Test.name, Test.age)
t = Test1()		//创建一个对象
print(t.show())		//通过对象调用里面的方法

2、继承了父类的非私有的属性和方法
子类方法中调用父类的属性和方法
方式1: 父类名.方法名(self, 参数)
方式2: super(子类名, self).方法名()

class Test:
    def __init__(self):
        self.name = 'tang'
        self.age = '24'
        self.__clazz = 1008
    def show1(self, house):
        self.house = house
        return '这是Test类中的show方法!!!house的值为:{}'.format(self.house)

class Test1(Test):
    def __init__(self):
        Test.__init__(self)	//这里是调用父类的__init__初始化方法,对属性进行赋值
        self.age = 18		
        //这里是覆盖父类中的属性self.age的值,在上面调用父类初始化的时候就已经默认将self.age也调用并赋值了
    def show(self):
        return '这里是调用Test类的name和age属性,name的值为:{},age的值为:{}'.format(self.name, self.age)
    def cat(self):
       return '这里是调用Test类中的方法show1,这里house的值为:{}'.format(self.show1('changsha'))
t = Test1()
print(t.cat())
print(t.show())
print(t.show1('shanghai'))	//调用父类的方法
print(t.name)		//这里是调用父类的属性
print(t.__clazz)      //这里会报错,因为这是父类的一个私有属性(私有方法一样)无法调用

#通过打印出来的值我们可以看到,打印的值均为子类的值,这是因为当查找属性时,默认是从子类中先找,在子类中没有再父类中找
3、重写
父类的方法不能满足子类的需求,则定义一个跟父类的名字相同的方法
每次对象调用则有限调用子类

class Test:
    def __init__(self):
        self.__name = 'tang'
        self.age = '24'
        self.__clazz = 1008
    def show(self, house):
        self.house = house
        return '这是Test类中的show方法!!!house的值为:{}'.format(self.house)

    def cat(self):
        return '这里是调用Test类中的方法show1,这里house的值为:{}'.format(self.show('hangzhou'))

class Test1(Test):
    def __init__(self):
        Test.__init__(self)
        self.__name = 'zhaoyun'
        self.age = 18
    def show(self,house):
        self.house = house
        return '这里是重写后的show方法,此时__name值为:{},gae的值为:{},house的值为:{}'.format(self.__name, self.age, self.house)
    # def cat(self):
    #    return '这里是调用Test类中的方法show1,这里house的值为:{}'.format(self.show('changsha'))
t = Test()		//创建对象
t1 = Test1()
print(t1.show('changsha'))	
//这里本来应当调用的是父类的show方法,但是子类中也定义了show方法,所以默认调用自身的,
因为在调用是会首先查找自身是否有这个方法,再去查找父类
print(t.show('shanghai'))   //这里是父类对象自身调用
print(t1.cat())		//在子类对象中调用父类的方法

总结:单继承中调用子类得属性和方法时,子类首先会在自身寻找,自身没有后再去父类中寻找,当父类中也为存在,或为私有属性(方法)时则报错
多继承
多继承:
多继承的查找顺序:python2.3-2.7的两种都存在,2.2以前只有经典类
经典类:遵循的原则:深度优先(从左到右的原则)
新式类:c3算法
格式:
class 子类名(父类1,父类2,父类3…):
pass

简单多继承

class Test1:
    def show(self):
        return '-------Test1类中的show方法------'
class Test2:
    def show(self):
        return '-------Test2类中的show方法------'
class Test3:
    def show(self):
        return '-------Test3类中的show方法------'

class Test4 (Test1, Test2, Test3):
    def cat(self):
        return self.show()
t = Test4()
print(t.show())    //这里你会发现打印的是Test1里面的show方法
print(t.cat())		//同上

继承中嵌套继承

class Test1:
    def show(self):
        return '-------Test1类中的show方法------'
class Test2:
    def show(self):
        return '-------Test2类中的show方法------'
class Test3:
    def show(self):
        return '-------Test3类中的show方法------'

class Tang1:
    def cat(self):
        return '这是Test1的子类Tang1'
class Tang2:
    def cat(self):
        return '这是Test1的子类Tang2'
class Tang3:
    def cat(self):
        return '这是Test3的子类Tang3'

class Test4 (Tang3,Tang2,Tang1,Test1, Test2, Test3):
    def cat(self):
        return self.show()
t = Test4()
print(t.show())		//得到的结果为Test1的show方法
print(t.cat())		//得到的结果也是Test1的show方法

总结:按照从左往右得方式查找,找到即停止,如果改类的父类为另一个类的子类,不会向改类的父类的父类查找,而是查找下一个,当所有的父类均没有时报错