继承父类中对象和方法的语法
class Parent: year = 2018 def coding(self): print('coding') class Sub(Parent): pass print(Sub.year) s1 = Sub() s1.coding()
4,继承对编程的作用
假设有个学生管理需求: class Student: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def study(self): print('正在学习中') def eat(self): print('正在吃饭中') 后续又要求添加老师管理需求: 学生的属性和技能也适用于老师,此时可以引用继承,减少代码的冗余 class Teacher(Student): pass t1 = Teacher('alex',30,'man') t1.eat() t1.study()
从逻辑上来说,如果学生有打游戏的技能,而老师并没有这个需求,因此继承到了老师并不需要的技能
正确姿势: 抽取公共的父类 (抽象)
抽象 : 抽取多个类中相同得部分,形成另一个类
把学生和老师共有的内容抽到另一个类中,学生和老师分别继承这个类,这样就避免了一个类继承到不需要的内容 因此应该先抽象,再继承
小结:
-
通过继承,避免了重复代码的编写。
-
继承的作用是可以直接使用父类已有的代码
-
通过抽象,避免了一个类继承到不需要的内容
-
抽象的作用是存储多个子类相同的属性和技能
-
正确地顺序应该先抽象,再继承
1,派生
class Person: • def __init__(self,name,age,sex): • self.name = name • self.age = age • self.sex = sex • def sayhi(self): • print('hello,') class Student(Person): # 学生属于人类,可以直接继承 • def __init__(self,number): # 加上一些学生特有的属性 • self.number = number • def study(self): • print('%s正在学习'%self.name)
-
派生指某个子类继承父类,并且拥有自己独特的属性或技能
-
该子类称之为派生类
-
只要子类中出现任何新内容,这就是一个派生类
2,覆盖
class A: age = 18#age相同 def f1(self):#f1相同 print(" A f1" ) pass class B(A): age1 = 19 def f1(self):#f1 self.f1() print(" B f1") b1 = B() print(b1.age) b1.f1()
小结:
-
子类出现了与父类重复的名字 称之为覆盖
-
(2 广度优先,并非绝对的广度优先,而是基于深度的广度优先。
先是深度优先,如果发现有共同父类,则返回。最后再查找共同父类
多重继承的菱形访问
class A: def ping(self): print('ping A:', self) class B(A): def pong(self): print('pong B:', self) class C(A): def pong(self): print('PONG C:', self) class D(B, C): def ping(self): super().ping() print('post-ping D:', self) def pingpong(self): self.ping() super().ping() self.pong() super().pong() C.pong(self) D().ping() D().pingpong()
mro
MRO步骤:
-
按照深度优先,从左到右的顺序
-
移除列表中的重复类型,仅保留最后一个
-
确保子类总在基类前面,并保留多继承定义顺序
对 bases 的调整会直接影响 mro 的顺序
查看访问路径
"super访问父类内容时 按照mro列表属性查找"
class S: def f1(self): print("s f1") class A(S): pass class B(S): def f1(self): print("b f1") pass class C(A,B): def f2(self): print("c f2") super().f1() print(C.mro()) c1 = C() c1.f2()
Tkinter GUI 类层次结构的 UML 简图
-
多个对象放在一起就是组合
-
一个对象将另一个对象作为自己的属性,就是组合
class Phone:#组合的代码 def __init__(self,phonenumber,operator,address): self.phonenumber = phonenumber self.operator = operator self.address = address def call(self,t): print("%s 正在拨号 %s" % (t.name,self.phonenumber)) class Person:#父类 def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age class Student(Person):#子类 def __init__(self,name,sex,age,number): super().__init__(name, sex, age) self.number = number def show_info(self): print(self.__dict__) def select_cursor(self): print("%s 正在选课...." % self.name) class Teacher(Person):#子类 def __init__(self,name,sex,age,salary,level): super().__init__(name,sex,age) self.salary = salary self.level = level def set_score(self): print("%s 正在为学生打分..." % self.name) stu = Student("乔峰","男",38,"007") p1 = Phone("1999999999","中国小米移动","上海浦东") stu.q = p1 #这里的q是变量名,相当于把p1赋值给q,通过stu来调用 stu.q.call(stu) #不能直接stu.p1.call()