继承
一、继承
1.什么是继承:在程序中继承是描述类与类之间的关系。例如:A类继承了B类,A类就能直接使用B类已经存在的方法和属性(A类称之为子类,B类称之为父类也叫基类)
2.为什么要使用继承:继承的一方可以直接使用被继承一方已经存在的方法和属性。其目的是为了提高代码的复用性。
class 父类名称: 类的内容 class 子类名称(父类名称): 类的内容 #在python中 一个子类可以同时继承多个父类
二、抽象
# 抽象指的是将一系列类中相同的特征和相同的行为抽取形成一个新的类,这个过程会产生一些原本业务不相关的类 class People: school = "Tinghua" def __init__(self, name, age): self.name = name self.age = age def say_hi(self): print("hello,i am %s" % self.name) class Teacher(People): def teach(self): print("正在教书.....") class Student(People): pass t = Teacher("qwe",35) t.say_hi() # hello,i am qwe t.teach() # 正在教书..... s = Student("asd",18) s.say_hi() # hello,i am asd
三、
1. 在python3中任何类都直接或者间接继承自object
2. object提供一系列方法,这样一来,无论是什么样的类,都可以直接是object中已经存在的方法
3. 一切皆对象:一切皆对象指的是在python中所使用到的数据都是对象
四、
class A: text = "haha" class B(A): text = "heihei" pass b = B() b.text = "xixi" print(b.text) # xixi" # 对象自己的 - > 所在类中 -> 找父类 - >父类的父类 -> ... -> 父类 ->Object
五、
派生:子类中与父类不同的内容就称之为派生类
覆盖:指的是子类出现了与父类完全相同(属性/方法)名称,根据查找顺序,就会优先找子类的,即覆盖了父类的内容
class Person: name = 'person' def say_hi(self): print("hello") class Student(Person): name = 'student' # 覆盖 age= 18 # 派生 def say_hi(self): # 覆盖 print("hello world!") stu = Student() print(stu.name) # student print(stu.age) # 18 stu.say_hi() # hello world!
六、
# 子类中使用父类的属性或方法 class Person: text = "321" def __init__(self,name ,age,gender): self.name = name self.age = age self.gender = gender def sleep(self): print("人类 躺着睡 午睡") def say_hi(self): print("my name is %s: my age is %s: my gender is %s:" % (self.name,self.age,self.gender),end="") class Student(Person): text = "123" def __init__(self,name,age,gender,number): # 由于父类已经存在一个方法可以完成这三个参数的初始化, # 所以可以直接调用父类的初始化完成这部分的初始化工作 # 方法一 # 指名道姓的调用 # Person.__init__(name,age,gender) # 方法二 在py2中不支持 super().__init__(name,age,gender) # 方法三 在py2中写法 # super(Student,self).__init__(name,age,gender) self.number = number def show_text(self): print(self.text) def say_hi(self): super().say_hi() print("my number %s" % self.number) s = Student("jack",20,"man","007") s.say_hi() # my name is jack: my age is 20: my gender is man:my number 007
七、
class MyList(list): def __init__(self,element_type): super().__init__() # 调用父类的初始化方法 来完成基本的初始化 self.element_type = element_type def append(self, object): """ :param object: 是要存储的元素 :return: 没有 """ if type(object) == self.element_type: #我们需要在这里访问父类的append函数来完成真正的存储操作 super(MyList,self).append(object) else: print("sorry sir, you element type not is %s" % self.element_type) # 创建是指定要存储的元素类型 m = MyList(int) # 当你有需求,是需要在创建对象时 干点什么事儿 那就该想到初始化方法 m.append(1) print(m[0]) m.append("121212")
八、组合
1. 什么是组合:将一个对象作为另一个对象的属性称之为组合(指的是对象与对象之间的关系)
2. 组合描述的是 什么拥有什么的关系 学生 有 书 学生有手机
3. 组合的目的:
也是为了重用现有代码
什么时候使用继承:分析两个类的关系,到底是不是:什么是什么的关系
什么时候使用组合:如果两个类之间 没有太大的关系,完全不属于同类
另外组合相比继承,耦合度更低了# 简单组合 class Person: # rose是一个字符串类型,这样Person类中就含有了str类的对象作为自己的属性 def __init__(self,name): self.name = name p = Person("rose") print(p.name) # rose# 复杂组合 class PC: def open_app(self,app_name): print("open %s" % app_name) class Student: def __init__(self,pc,notebook): self.pc = pc self.notebook = notebook pass pc = PC() notebook = PC() stu = Student(pc,notebook) stu.pc.open_app("pycharm") # open pycharm stu.notebook.open_app("pycharm") # open pycharm # stu.open_app("pycharm") # 报错
九、
多继承: 一个类可以同时继承多个父类
菱形继承:一个类有多个父类,多个父类之间又同时继承另一个父类,就产生了菱形继承
经典类:没有继承自object的类就成为经典类,只出现再py2中
新式类:直接或者间接继承了object的类就是新式类,py3全部是新式类,py2中继承了object也就是新式类
9.1 多继承
""" 多继承下出现了的相同的属性/函数的查找顺序 """ # super在访问父类属性时,查找顺序,严格按照mro列表的顺序来查看真正的继承顺序 class A: def test(self): print("from A") super().test() # A类没有父类,正常应该报错,但是执行成功了 class B: def test(self): print("from B") class C(A,B): pass c = C() c.test() # from A # from B print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
9.2 菱形继承
在经典类中:查找顺序按照深度优先:E -> B -> A -> C -> D
在新式类中:产找顺序按照先深度再广度:E -> B -> C -> D -> A -> object
""" 菱形继承 """ class A: a = 1 pass class B(A): a = 2 pass class C(A): a = 3 pass class D(A): a = 4 pass class E(B,C,D): a = 5 pass e = E() print(e.a) # 新式类:E B C D A object # 经典类:E B A C D
十、接口
接口是一套协议规范,具体表现一堆只有方法声明而没有实现体的方法
使用接口可以提高程序的扩展性
只要对象按照接口规定的方法来实现。使用者就可以无差别使用所有对象
问题:无法限制子类必须真正的实现接口中的功能
class USB: def open(self): pass def close(self): pass def read(self): pass def write(self): pass class Mouse(USB): def open(self): print("鼠标开机.....") def close(self): print("鼠标关机了...") def read(self): print("获取了光标位置....") def write(self): print("鼠标不支持写入....") def pc(usb_device): usb_device.open() usb_device.read() usb_device.write() usb_device.close() m = Mouse() # 将鼠标传给电脑 pc(m)
十一、抽象类
11.1 什么是抽象类
指的是没有函数体的方法,用@abc.abstractmethod装饰器
如果类中具备抽象方法,那么这个类就成为抽象类
11.2 抽象类的特点
不能直接实例化 必须有子类覆盖了所有抽象方法后才能实例化子类
11.3 与
抽象类既可以有抽象方法,也可以有普通方法
接口是指只有方法声明而没有函数体,接口中所有方法都是抽象方法
接口的出现是为了提高扩展性,抽象类是为了限制子类必须按照接口要求来实现
import abc class Test(metaclass=abc.ABCMeta): @abc.abstractmethod def say_hi(self): pass def info(self): print("my name is test") class TT(Test): def say_hi(self): print("I am TT obj") t = TT() t.say_hi()import abc class USB(metaclass=abc.ABCMeta): @abc.abstractmethod def open(self): pass @abc.abstractmethod def work(self): pass @abc.abstractmethod def close(self): pass class Mouse(USB): def open(self): print("mouse opened") def close(self): print("mouse closed") def work(self): print("mouse working...") class PC: def conntent_device(self,usb_device): usb_device.open() usb_device.work() usb_device.close() # 创建一个鼠标设备 mouse = Mouse() pc = PC() pc.conntent_device(mouse) # c = USB() # 直接实例化会报错