Python笔记(十三):类的继承

类有经典类和新式类,经典类即class people: 新式类即class people(object):
新式类比经典类多了一些新的用法,比如在多继承的时候
- 在多继承时,如果继承的几个类都有构造函数,则按顺序只走第一个的构造函数
- Python2中,经典类按深度优先继承,新式类按广度优先继承
- Python3中,经典类和新式类都是广度优先。



继承

可以直接继承父类的属性,减少了代码书写量

class people:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def eat(self):
        print("%s is eating..." % self.name)
    def talk(self):
        print("%s is talking..." % self.name)
    def sleep(self):
        print("%s is sleeping..." % self.name)
class man(people):
    pass

其中people为父类,man为子类
man完全继承了people中定义的姓名和年龄变量,以及后面的方法;

m1 = man("Evan",22)
m1.eat()

>> Evan is eating...

重构父类方法

可以在继承父类方法的基础上,再增加新功能;

class man(people):
    def run(self):
        print("%s is running..." % self.name)

    def sleep(self):
        people.sleep(self)
        print("man is sleeping")

m1 = man("Evan",22)
m1.sleep()

>> Evan is sleeping...
>> man is sleeping

重构了父类中的方法,先调用了父类的方法,然后再执行子类的方法,这样两个结果都能得到。

如果子类中定义的方法和父类的重复了,则会执行子类的方法,将父类的覆盖了。

子类中增加属性

方法一:

class man(people):
    def __init__(self,name,age,money):
        people.__init__(self,name,age)      
        self.money = money
        print("%s 出生自带 %s 钱" %(self.name,self.money))

再次调用父类的构造函数,然后在单独写要增加的属性。

方法二:

class man(people):
    def __init__(self,name,age,money):
        super(man,self).__init__(name,age)
        self.money = money
        print("%s 出生自带 %s 钱" %(self.name,self.money))

这种方法的好处在于:
1、如果父类改名字了,不用再进到每个子类中修改。
2、如果是继承多个父类,不用每个父类单独写一句调用构造函数。

多继承

经典类和新式类
定义的类,后面什么也不加就是经典类,加上object即为新式类;
新式类比经典类多了一些升级用法

比如:在子类中增加属性的方法二所用的super即新式类中的用法。

新式类的多继承:

class people(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def eat(self):
        print("%s is eating..." % self.name)
    def talk(self):
        print("%s is talking..." % self.name)
    def sleep(self):
        print("%s is sleeping..." % self.name)

class relation(object):
    def make_friends(self,obj):
        print("%s is making friends with %s" % (self.name,obj.name))

class man(people,relation):
    def __init__(self,name,age,money):
        super(man,self).__init__(name,age)
        self.money = money
        print("%s 出生自带 %s 元钱" %(self.name,self.money))

class woman(people,relation):
    def get_birth(self):
        print("%s has borned a baby..." % self.name)

m1 = man("Evan",22,10)
w1 = woman("HanMM",20)
m1.make_friends(w1)

>> Evan 出生自带 10 元钱
>> Evan is making friends with HanMM
  • relation并没有写构造函数,为什么可以直接传参数?
    因为在people中已经定义了这些属性,这些名字已经有了
  • 在上述例子中,relation类中传入的参数obj其实就是输入的w1实例对象

继承示例:学校、讲师、学生

程序:

class School(object):
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
        self.students = []
        self.staffs = []
    def enroll(self,stu_obj):
        print("为学员%s 办理注册手续" %stu_obj.name)
        self.students.append(stu_obj)
    def hire(self,staff_obj):
        self.staffs.append(staff_obj)
        print("雇佣新员工%s" % staff_obj.name)

class SchoolMember(object):
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def tell(self):
        pass

class Teacher(SchoolMember):
    def __init__(self,name,age,sex,salary,course):
        super(Teacher,self).__init__(name,age,sex)
        self.salary = salary
        self.course = course
    def tell(self):
        print('''
        ------ info of Teacher:%s ------
        Name:%s
        Age:%s
        Sex:%s
        Salary:%s
        Course:%s
        '''%(self.name,self.name,self.age,self.sex,self.salary,self.course))
    def teach(self):
        print("%s is teaching course [%s]" %(self.name,self.course))

class Student(SchoolMember):
    def __init__(self,name,age,sex,stu_id,grade):
        super(Student,self).__init__(name,age,sex)
        self.stu_id = stu_id
        self.grade = grade
    def tell(self):
        print('''
        ------ info of Student:%s ------
        Name:%s
        Age:%s
        Sex:%s
        Stu_id:%s
        Grade:%s
        ''' %(self.name,self.name,self.age,self.sex,self.stu_id,self.grade))
    def pay_tuition(self,amount):
        print("%s has paid tution for $%s" %(self.name,amount))


school = School("东方高中","洛阳")
t1 = Teacher("Lina",48,"female",20000,"Python")
t2 = Teacher("Tony",56,"male",8000,"Linux")

s1 = Student("Evan",22,"male",1301,"Python")
s2 = Student("Alan",24,"male",1302,"Linux")

t1.tell()
s1.tell()
school.hire(t1)
school.enroll(s1)
school.enroll(s2)

print(school.students)
print(school.staffs)
school.staffs[0].teach()

for stu in school.students:
    stu.pay_tuition(5000)

SchoolMember()暂时没写什么,但如果以后再添加一些东西,比如将所有学校成员再添加一种属性,就方便了

程序运行结果:

        ------ info of Teacher:Lina ------
        Name:Lina
        Age:48
        Sex:female
        Salary:20000
        Course:Python


        ------ info of Student:Evan ------
        Name:Evan
        Age:22
        Sex:male
        Stu_id:1301
        Grade:Python

雇佣新员工Lina
为学员Evan 办理注册手续
为学员Alan 办理注册手续
[<__main__.Student object at 0x00000000028BA278>, <__main__.Student object at 0x00000000028BA2B0>]
[<__main__.Teacher object at 0x00000000028BA208>]
Lina is teaching course [Python]
Evan has paid tution for $5000
Alan has paid tution for $5000

解析:

  • 定义学校
    • 属性:校名、地址、学生、员工
    • 方法:学生入学、雇佣新教师
  • 定义学校成员
    • 属性:姓名、年龄、性别
    • 方法:暂空
  • 定义教师
    • 属性:姓名、年龄、性别、工资、教授课程
    • 方法:tell(输出教师信息)、教课
  • 定义学生
    • 属性:姓名、年龄、性别、学号、学科
    • 方法:tell(输出学生信息)、付学费

首先定义了学校,由于学校和老师、学生直接没有直接关系
所以又定义了SchoolMember类,继承School,新增了教师和学生共有的属性;
Teacher和Student继承SchoolMember类

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值