Python面向对象--继承
1.继承
在现实生活中,继承一般指的是子女继承父辈的财产,父辈有的财产,子女能够直接使用。
程序里的继承
继承是面向对象软件设计中的一个概念,与多态、封装共为面向对象的三个基本特征。继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。
在程序中,继承描述的是多个类之间的所属关系。
如果一个类A里面的属性和方法可以复用,则可以通过继承的方式,传递到类B里。
那么类A就是基类,也叫做父类;类B就是派生类,也叫做子类。
格式:
继承:
Student,Employee,Doctor都属于人类
具有相同的属性,相同的代码存在冗余,可读性不高
提取相同的代码,子类继承父类--->Person
Student,Employee,Doctor===》继承Person
class 子类名(父类名):
pass
1 class Person:
2 def __init__(self, name, age):
3 self.name = name
4 self.age = age
5
6 def eat(self):
7 print(self.name + '正在吃饭...')
8
9 def run(self):
10 print(self.name + '正在跑步...')
11
12
13 class Student(Person):
14 pass
15
16
17 class Employee(Person):
18 pass
19
20
21 class Doctor(Person):
22 pass
23
24
25 stu = Student('tom', 18)
26 stu.run()
27 stu.eat()
28
29 e = Employee('jack', 20)
30 e.run()
31 e.eat()
32
33 d = Doctor('smith', 21)
34 d.run()
35 e.eat()
36
37 '''
38 tom正在跑步...
39 tom正在吃饭...
40 jack正在跑步...
41 jack正在吃饭...
42 smith正在跑步...
43 jack正在吃饭...
44 '''
2.super
1、如果类中不定义__init__,调用父类 super class 的__init__
2、如果类继承父类也需要定义自己的__init___,就需要在当前类的__init__调用父类的__init__
3、如何调用父类的__init__:
(1).super().__init__(参数)
(2).super(类名,对象).__init__(参数)
4、如果父类有某个方法,子类也定义一个同样的方法,则只读取子类的方法。默认搜索原则:先找当前子类,再找父类。
如父类的Person也有eat(),但子类的Student类也有eat(),则先调用子类Student类的eat(),再调用父类的eat()
5、当父类提供的方法不满足子类的需求时,就需要在子类中定义一个同名的方法,这种行为就叫做重写
6、子类的方法中也可以调用父类的方法,调用方法:super().方法名
例如Student类的eat,:super.eat()
1 class Person:
2 def __init__(self, name, age):
3 self.name = name
4 self.age = age
5
6 def eat(self):
7 print(self.name + '正在吃饭...')
8
9 def run(self):
10 print(self.name + '正在跑步...')
11
12
13 class Student(Person):
14 def __init__(self, name, age, clazz):
15 super().__init__(name, age)
16 self.clazz = clazz
17 print('---------->student的init')
18
19 def study(self, course):
20 print('{}正在学{}'.format(self.name, course))
21
22 def eat(self, food):
23 super().eat()
24 print('{}正在吃饭...喜欢吃:{}'.format(self.name, food))
25
26
27 class Employee(Person):
28 def __init__(self, name, age, salary, manager):
29 super().__init__(name, age)
30 self.salary = salary
31 self.manager = manager
32
33
34 class Doctor(Person):
35 def __init__(self, name, age, patients):
36 super(Doctor, self).__init__(name, age)
37 self.patients = patients
38
39
40 stu = Student('tom', 18, 'python1906')
41 stu.run()
42 stu.eat('万州烤鱼')
43 stu.study('python基础')
44 e = Employee('jack', 20, 10000, 'king')
45 # e.run()
46
47 list1 = ['张三', '李四', '王五']
48 d = Doctor('smith', 21, list)
49 # e.run()
50
51 '''
52 tom正在跑步...
53 tom正在吃饭...
54 tom正在吃饭...喜欢吃:万州烤鱼
55 tom正在学python基础
56 '''
小练习
编写一个简单的工资管理程序,系统可以管理以下四类人,工人(rorker)、销售员(salesman)
所有的员工都具有员工号,姓名,工资等属性,
有设置姓名,获取姓名,获取员工号,计算工资等方法。
1)工人:工人具有工作小时数和时薪的属性,工资计算法方法为工作小时数*时薪。
2)销售员:具有销售额和提成比例的属性,工资计算方法为销售额*提成比例。
请根据以上要求设计合理的类,完成以下功能:
1)添加所有类型的人员
2)计算月薪
3)显示所有人工资情况
1 class Person: 2 def __init__(self, no, name, salary): 3 self.no = no 4 self.name = name 5 self.salary = salary 6 7 def __str__(self): 8 msg = '工号:{},姓名:{},本月工资:{}'.format(self.no, self.name, self.salary) 9 return msg 10 11 def getSalary(self): 12 return self.salary 13 14 15 class Worker(Person): 16 17 def __init__(self, no, name, salary, hours, per_hour): 18 super(Worker, self).__init__(no, name, salary) 19 self.hours = hours 20 self.per_hours = per_hour 21 22 def getSalary(self): 23 money = self.hours * self.per_hours 24 self.salary += money 25 return self.salary 26 27 28 class Salesman(Person): 29 def __init__(self, no, name, salary, salemoney, percent): 30 super(Salesman, self).__init__(no, name, salary) 31 self.salemoney = salemoney 32 self.percent = percent 33 34 def getSalary(self): 35 money = self.salemoney * self.percent 36 self.salary += money 37 return self.salary 38 39 40 # 创建子类对象 41 42 worker = Worker('007', 'tom', 2000, 180, 18) 43 salary = worker.getSalary() 44 print('007号月薪是:', salary) 45 print(worker) 46 47 saler = Salesman('008', 'jack', 5000, 5000000, 0.003) 48 salary = saler.getSalary() 49 print('008号月薪是:', salary) 50 print(saler) 51 52 ''' 53 007号月薪是: 5240 54 工号:007,姓名:tom,本月工资:5240 55 008号月薪是: 20000.0 56 工号:008,姓名:jack,本月工资:20000.0 57 '''
3.多继承
Python中针对类提供了一个内置属性__mro__可以用来查看方法的搜索顺序。
MRO 是method resolution order的简称,主要用于在多继承时判断方法属性的调用顺序。
print(C.__mro__)
输出结果:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
在调用方法时,按照__mro__的输出结果从左至右的顺序查找。
如果再当前类中找到方法,就直接执行,不再向下搜索。
如果没有找到,就顺序查找下一个类中是否有对应的方法,如果找到,就直接执行,不再继续向下搜索。
如果找到了最后一个类,依然没有找到方法,程序就会报错。
新式类和旧式(经典)类
object是Python中所有对象的基类,提供了一些内置的属性和方法,可以时候用dir函数查看。
新式类:以object为基类的类,推荐使用
经典类:不以object为基类的类,不推荐使用
在 Python3.x 以后定义类时,如果没有指定父类,这个类会默认继承自 object,所以,python3.x版本定义的类都是新式类。
在Python2.x中定义类时,如果没有指定父类,则不会继承自object.
为了保证代码在Python2.x和Python3.x中都能够运行,在定义类时,如果一个类没有父类,建议统一继承自'object'
class 类名(object):
pass
1 class P2:
2 def foo(self):
3 print('p2--->foo')
4
5
6 class C1(P1, P2):
7 pass
8
9
10 class C2(P1, P2):
11 def bar(self):
12 print('C2--->bar')
13
14
15 class D(C1, C2):
16 pass
17
18 d = D()
19
20 print(D.__mro__)
21
22 '''
23 (<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>,
24 <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
25 '''
继承搜索顺序
1 class A:
2 def foo(self):
3 print('p1--->foo')
4
5 def bar(self):
6 print('p1--->bar')
7
8
9 class B:
10 def foo(self):
11 print('p2--->foo')
12
13
14 class C(A):
15 pass
16
17
18 class D(A):
19 def bar(self):
20 print('C2--->bar')
21
22
23 class E(C, B):
24 pass
25
26
27 class F(C, B, D):
28 pass
29
30
31 class G(D, B):
32 pass
33
34
35 g = G()
36
37 print(F.__mro__)
38
39 '''
40 (<class '__main__.F'>, <class '__main__.C'>, <class '__main__.B'>,
41 <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)
42 '''
F的查找顺序,先C-->B-->D-->A-->object
先按继承的顺序寻找,到最后一个再按往上一层级的寻找
作者:Ambitious
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!