欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python中类的应用(继承与派生)

程序员文章站 2022-05-10 22:49:44
继承与派生 什么是继承 继承是一种新建类的方式,新建的类称为子类,子类会遗传父类的属性,可以减少代码冗余, 在python中,子类(派生类)可以继承一个或者多个父类(基类...

继承与派生

什么是继承

继承是一种新建类的方式,新建的类称为子类,子类会遗传父类的属性,可以减少代码冗余,
在python中,子类(派生类)可以继承一个或者多个父类(基类,超类)

例如:

class Parent1:
    pass
class Parent2(object):
    pass
class Sub1(Parent1):
    pass
class Sub2(Parent1,Parent2):
    pass

print(Sub1.__bases__)    #查看类的父类
print(Sub2.__bases__)

print(Parent1.__bases__)  #在python3新建的类,默认都有一个父类(object)  #在python2中,默认是没有父类,可以添加(object)为父类
print(Parent2.__bases__)

python中类的分类

在python2中:

1、经典类,指的就是没有继承object类的类,以及该类的子类

2、新式类,指的就是继承object类的类,以及该类的子类

在python3中:

统一都是新式类

例如:

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 OldboyStudent(OldboyPeople):
    def learn(self):
        print('%s is learning' %self.name)
    def tell_info(self):
        print('我是学生:',end='')
class OldboyTreacher(OldboyPeople):
    def teach(self):
        print('%s is teaching' %self.name)
    def tell_info(self):
        print('我是老师:',end='')
        print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))
stu1=OldboyStudent('lqx','19','male')
teaching=OldboyTreacher('egon','23','female')

print(stu1.__dict__)
print(stu1.school)
# print(stu1.x)  #查找顺序,对象->子类->父类 没有就抛异常
print(teaching.__dict__)

# 如果子类有这个函数,就不会去父类去找
stu1.tell_info()
teaching.tell_info()

#属性查找:
class Foo:
    def f1(self):
        print('foo.f1')
    def f2(self):       #self应该为Bar初始化的obj对象
        print('foo.f2')
        self.f1()   #Bar初始化的obj.f1()
class Bar(Foo):
    def f1(self):
        print('bar.f1')
obj=Bar()
print(obj.__dict__)
obj.f2()  #先在bar类中查找,如果没有就会去父类查找,

# >>>foo.f2
# bar.f1

子类重用父类的方法

指名道姓的使用

#子类指名道姓使用父类属性
#实现学生还有课程、学号
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 课程:%s 学号:%s>' %(self.name,self.age,self.sex,self.coutse,self.stu_id))
class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,coutse,stu_id):
        OldboyPeople.__init__(self,name,age,sex)   #子类指名道姓使用父类属性
        self.coutse=coutse
        self.stu_id=stu_id
    def learn(self):
        print('%s is learning' %self.name)
    def tell_info(self):
        print('我是学生:',end='')
        OldboyPeople.tell_info(self)    #子类指名道姓使用父类属性


stu1=OldboyStudent('lqx','19','male','python','123')
stu1.tell_info()

使用super来调用父类的方法

1、之前使用指名道姓的引用另一个类,或者父类的方法。

2、现在使用super(本类名.self).方法 的方式调用父类的方法

3、这种方法只能调用父类的方法

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 OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,course):
        # OldboyPeople.__init__(self,name,age,sex)
        super(OldboyStudent,self).__init__(name,age,sex)
        self.course=course

    def tell_info(self):
        print('我是学生: ',end='')
        # OldboyPeople.tell_info(self)
        super(OldboyStudent,self).tell_info()

stu1=OldboyStudent('lqx','12','male','python')
print(stu1.name,stu1.age,stu1.sex,stu1.course)
stu1.tell_info()

super方法

class Foo:
    # def f2(self):
        # print('>>>>2')
    def f1(self):
        print('foo.f1')
        Foo.f2(123)
class Bar:
    def f2(self):
        print('bar f2')
class Sub(Bar,Foo):
    pass

s=Sub()
print(Sub.mro())  #[, , , ]

s.f1()  #说明严格按照mro()中的查找顺序来查找

#查找顺序,Sub->Bar->Foo

组合的使用

#学生有年龄名字,性别,学号,还有生日,使用组合添加出生日
#组合区别于继承,什么有什么的一种关系
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 课程:%s 学号:%s>' %(self.name,self.age,self.sex,self.coutse,self.stu_id))
class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,coutse,stu_id,date_obj):
        OldboyPeople.__init__(self,name,age,sex)
        self.coutse=coutse
        self.stu_id=stu_id
        self.birth=date_obj   #3、把date_obj添加到self这个对象中

    def learn(self):
        print('%s is learning' %self.name)
    def tell_info(self):
        print('我是学生:',end='')
        OldboyPeople.tell_info(self)

class OldboyTreacher(OldboyPeople):
    def __init__(self,name,age,sex,level,salary):
        OldboyPeople.__init__(self, name, age, sex)
        self.level = level
        self.salary = salary
    def teach(self):
        print('%s is teaching' %self.name)
    def tell_info(self):
        print('我是老师:',end='')
        print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))

class Date:
    def __init__(self,year,mon,day):
        self.year = year
        self.mon = mon
        self.day = day

    def tell_birth(self):
        print('出生日期是:%s-%s-%s' % (self.year, self.mon, self.day))

date_obj=Date('1921',21,23)   #1、先初始化生日得到一个对象
stu1=OldboyStudent('lqx','19','male','python','12',date_obj)  #2、初始化学生类,把初始化生日的对象带入一起初始化
stu1.birth.tell_birth()   #4、就可以调用对象stu1中birth的属性

teacher1=OldboyTreacher('www','123','female',10,12)
date_obj2=Date(1990,2,18)
teacher1.brith=date_obj2


# 添加一个生日,把生日任何人都有生日,把生日放到父类中,初始化的时候就会有生日
class OldboyPeople:
    school='oldboy'

    def __init__(self,name,age,sex,date_obj):
        self.name=name
        self.age=age
        self.sex=sex
        self.birth=date_obj
    def tell_info(self):
        print('<名字:%s 年龄:%s 性别:%s >' %(self.name,self.age,self.sex))

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,coutse,stu_id,date_obj):
        OldboyPeople.__init__(self,name,age,sex,date_obj)
        self.coutse=coutse
        self.stu_id=stu_id


    def learn(self):
        print('%s is learning' %self.name)
    def tell_info(self):
        print('我是学生:',end='')
        OldboyPeople.tell_info(self)
        print('课程:%s 学号:%s' %(self.coutse,self.stu_id))

class OldboyTreacher(OldboyPeople):
    def __init__(self,name,age,sex,level,salary,date_obj):
        OldboyPeople.__init__(self, name, age, sex,date_obj)
        self.level = level
        self.salary = salary
    def teach(self):
        print('%s is teaching' %self.name)
    def tell_info(self):
        print('我是老师:',end='')
        print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))

class Date:
    def __init__(self,year,mon,day):
        self.year = year
        self.mon = mon
        self.day = day
    def tell_birth(self):
        print('出生日期是:%s-%s-%s' % (self.year, self.mon, self.day))

class OldboySale(OldboyPeople):
    def __init__(self,name,age,sex,kpi,date_obj):
        OldboyPeople.__init__(self,name,age,sex,date_obj)
        self.kpi=kpi

    def tell_info(self):
        print('销售:%s',end='')
        OldboyPeople.tell_info(self)

date_obj=Date('1921',21,23)   
stu1=OldboyStudent('lqx','19','male','python','12',date_obj)  
stu1.birth.tell_birth()  

date_obj2=Date(1990,2,18)
teacher1=OldboyTreacher('www','123','female',10,12,date_obj2)
teacher1.birth.tell_birth()
print(teacher1.__dict__)

date_obj1=Date(1800,12,32)
sale1=OldboySale('mmp','12','female',7.1,date_obj1)
print(sale1.__dict__)
sale1.birth.tell_birth()



#学生选课,添加选择的课程,在初始化的时候初始化一个属性为list
class OldboyPeople:
    school='oldboy'

    def __init__(self,name,age,sex,date_obj):
        self.name=name
        self.age=age
        self.sex=sex
        self.birth=date_obj
    def tell_info(self):
        print('<名字:%s 年龄:%s 性别:%s >' %(self.name,self.age,self.sex),end='')

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,date_obj,stu_id):
        OldboyPeople.__init__(self,name,age,sex,date_obj)
        self.coutse=[]
        self.stu_id=stu_id


    def learn(self):
        print('%s is learning' %self.name)
    def tell_info(self):
        print('我是学生:',end='')
        OldboyPeople.tell_info(self)
        print('学号:%s' %self.stu_id)

class OldboyTreacher(OldboyPeople):
    def __init__(self,name,age,sex,level,salary,date_obj):
        OldboyPeople.__init__(self, name, age, sex,date_obj)
        self.level = level
        self.salary = salary
        self.courses=[]
    def teach(self):
        print('%s is teaching' %self.name)
    def tell_info(self):
        print('我是老师:',end='')
        print('<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex))

class Date:
    def __init__(self,year,mon,day):
        self.year = year
        self.mon = mon
        self.day = day
    def tell_birth(self):
        print('出生日期是:%s-%s-%s' % (self.year, self.mon, self.day))

class OldboySale(OldboyPeople):
    def __init__(self,name,age,sex,kpi,date_obj):
        OldboyPeople.__init__(self,name,age,sex,date_obj)
        self.kpi=kpi

    def tell_info(self):
        print('销售:%s',end='')
        OldboyPeople.tell_info(self)


class Course:
    def __init__(self,name,price,period):
        self.name=name
        self.price=price
        self.period=period
    def tell_info(self):
        print('课程详细信息:(%s,%s,%s)' %(self.name,self.price,self.period))

Python=Course('python自动化',4000,'3mon')
Linux=Course('linux学习',2000,'3mon')

# date_obj=Date(1990,12,32)
# tearch1=OldboyTreacher('egon','19','male',100,3000,date_obj)
# tearch1.courses.append(Python)
# for course in tearch1.courses:
#     course.tell_info()

date_obj=Date(1994,21,12)
stu1=OldboyStudent('LQX',29,'male',date_obj,'1')
stu1.coutse.append(Linux)
stu1.coutse.append(Python)
stu1.tell_info()
for coutse in stu1.coutse:
    coutse.tell_info()

抽象类

主要使用abc模块,实现归一化,父类有的方法,子类必须有。

需要在父类的方法头部加上@abc.abstractclassmethod

例如:

class File(metaclass=abc.ABCMeta):
    @abc.abstractmethod 
    def read(self):   #必须要定义下面的方法,如果没有就不让实例化
        pass
    @abc.abstractmethod
    def write(self):
        pass
class Sata(File):
    def read(self):
        pass
    def write(self):
        pass
    def asb(self):
        print('adsf')
Fil=Sata()
Fil.asb()
print(Sata.mro())

继承的实现原理

1、继承顺序:

经典类:当类是经典类时,多继承情况下,在要查找属性不存在时,会按照深度优先的方式查找下去

新式类:当类是新式类时,多继承情况下,在要查询属性不存在时,会按照广度优先的方式查找下去

2、使用属性来查看继承的顺序:

print(类名.mro())

class A(object):
    # def test(self):
    #     print('from A')
    pass

class B(A):
    # def test(self):
    #     print('from B')
    pass

class C(A):
    # def test(self):
    #     print('from C')
    pass
class D(B):
    # def test(self):
    #     print('from D')
    pass

class E(C):
    # def test(self):
    #     print('from E')
    pass
class F(D,E):
    # def test(self):
    #     print('from F')
    pass

f1=F()
print(F.mro())