封装 继承 多态
1. 封装
1. 封装的理论: """ 封装 封装指的就是把数据与功能都整合到一起,听起来是不是很熟悉,没错,我们之前所说的”整合“二字其实就是封装的通俗说法。
什么是封装 在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用。 要了解封装,离不开“私有化”,就是将类或者是函数中的某些属性限制在某个区域之内,外部无法调用。 为什么要封装 封装数据的主要原因是:保护隐私(把不想别人知道的东西封装起来) """ class Student(): __school = 'SH' # _Student__school def __init__(self, name, age, gender): self.__name = name self.age = age self.gender = gender def __func(self): print('from func') def get_name(self): return self.__name def set_name(self,v): if type(v) is str: Student._Student__name = v return else: print('必须是字符串') def del_name(self): del self.__name print('属性已删除') """ 第一种方法: 必须一一对应 第一个是 get set del 顺序不能乱 执行相关操作的时候 装饰器会判断执行对应的函数功能 """ name = property(get_name,set_name,del_name,) stu = Student('huang',18,'male') # print(stu.name) del stu.name # 删除 stu.name = 'lu' # 修改 print(stu.name) # 查看 # print(stu.__dict__)
2. 继承
""" 1. 什么是继承? 继承就是一种新建类的方式,新建出来的类我们称之为 '子类或者叫派生类',被继承的类我们叫做 基类 当然 出来的类的子类都是可以遗传父类的所有属性 2. 为什么要用继承? 类解决了什么问题:对象之间的代码冗余问题 继承解决了什么问题:类与类之间的代码冗余问题 3. 怎么使用继承? 经典类:没有继承object的类或子子类都是称之为经典类 python2.x本版才有经典类 3.x版本只有新式类了 新式类:继承了object的累的子子类都是新式类 再有在Python2中才区分经典类和新式类,如果是Python3的版本,所有的类都是新式类,也就是说在Python3中默认的类都是继承了object类,在Python3中没有了经典类和新式类的说法了. """ 继承代码显示如下: class Foo: pass class Bar: pass class Order(Foo): pass # Order 类继承了 Foo类,Order就称之为子类 Foo类就是叫做父类 或者是基类 # 单继承:一次只继承一个父类 若是继承多个 就叫多继承 class Stu(Foo,Bar): pass # 多继承的类 Stu 就是子类 Foo 和 Order 就是父类 print(Stu.__bases__) # (<class '__main__.Foo'>, <class '__main__.Bar'>) # 内置函数 查看子类继承了多少个父类 """ 继承的实际案例""" 两种方法 第一种:不依赖于继承来实现 class Teachar_Stu(): scholl = 'SH' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender def func(self): print('from func') class Stu(Teachar_Stu): def __init__(self, uid, class_name, name, age, gender): self.uid = uid self.class_name = class_name Teachar_Stu.__init__(self, name, age, gender) # 这种类来调用方法 不依赖与继承 子类里面一定再次调用父类的方法 指名道姓的调用 def index(self): print('%s 同学喜欢打篮球' % self.name) class Tar(Teachar_Stu): def __init__(self, evol, salary, name, age, gender): self.evol = evol self.salary = salary Teachar_Stu.__init__(self, name, age, gender) # 这种类来调用方法 不依赖与继承 def scoring(self, student, fraction): print('%s 老师给 %s 同学打了 %s 分' % (self.name, student, fraction)) sti1 = Stu('D15', '12班', 'huang', 18, 'male') sti1.index() tar1 = Tar('10级', 35000, 'hai', 28, 'female') tar1.scoring(tar1.name, 90) 第二种 class Teachar_Stu(): scholl = 'SH' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender def func(self): print('from func') class Stu(Teachar_Stu): def __init__(self, uid, class_name, name, age, gender): self.uid = uid self.class_name = class_name super(Stu, self).__init__( name, age, gender) # 这种写法是 python2.x版本的 super().__init__(name,age,gender) # 这种是python3.x版本的写法 def index(self): print('%s 同学喜欢打篮球' % self.name) class Tar(Teachar_Stu): def __init__(self, evol, salary, name, age, gender): self.evol = evol self.salary = salary super(Tar, self).__init__( name, age, gender)
super().__init__(name,age,gender) # 这种是python3.x版本的写法
def scoring(self, student, fraction): print('%s 老师给 %s 同学打了 %s 分' % (self.name, student, fraction)) sti1 = Stu('D15', '12班', 'huang', 18, 'male') sti1.index() tar1 = Tar('10级', 35000, 'hai', 28, 'female') tar1.scoring(tar1.name, 90)
3. 单继承下的查找
单继承 class A(): def f2(self): pass class Foo(A): def f1(self): # _Foo__f1 print('from Foo.f1') def f2(self): print('from Foo.f2') self.f1() class Bar(Foo): def f1(self): # _Bar__f1 print('from Bar.f1') # from Bar.f1 """单继承下的属性查找:先从对象自己名称空间中查找,然后去产生这个对象的类中查找,最后去继承的父类中查找.""" obj = Bar() obj.f2() """ from Foo.f2 from Bar.f1 """ 如果有隐藏属性: class A(): def f2(self): pass class Foo(A): def __f1(self): # _Foo__f1 print('from Foo.f1') def f2(self): print('from Foo.f2') self.__f1() # _Foo__f1 class Bar(Foo): def __f1(self): # _Bar__f1 print('from Bar.f1') # from Bar.f1 """单继承下的属性查找:先从对象自己名称空间中查找,然后去产生这个对象的类中查找,最后去继承的父类中查找. 如果有隐藏属性 在对象中找不到 去类中 类中找不到去父类 父类中找到了 一样是调用父类的隐藏属性 """ obj = Bar() obj.f2()
4. 多继承下的属性查找
多继承下分菱形查找和非菱形查找 菱形查找分 经典类 和 新式类 经典类:按照深度优先的查找顺序 新式类:按照广度优先查找 # 在python2中,未继承object的类及其子类,都是经典类 def test(self): print('from G') class E(G): def test(self): print('from E') class F(G): def test(self): print('from F') class B(E): def test(self): print('from B') class C(F): def test(self): print('from C') class D(G): def test(self): print('from D') class A(B, C, D): # def test(self): # print('from A') pass obj = A() obj.test() # 如上图,查找顺序为:obj->A->B->E->G->C->F->D->object # 可依次注释上述类中的方法test来进行验证,注意请在python2.x中进行测试 类及其子类,都是经典类 class G(object): def test(self): print('from G') class E(G): def test(self): print('from E') class F(G): def test(self): print('from F') class B(E): def test(self): print('from B') class C(F): def test(self): print('from C') class D(G): def test(self): print('from D') class A(B,C,D): # def test(self): # print('from A') pass obj = A() obj.test() # 如上图,查找顺序为:obj->A->B->E->C->F->D->G->object # 可依次注释上述类中的方法test来进行验证 """python3中都是新式类,都是广度优先查询"""
5. super 和 mro的使用
class A: def test(self): super().test() class B: def test(self): print('from B') class C(A, B): pass s = A() s.test() # 首先要清楚当前产生对象的是那个类 super的作用基本就是调用父类的功能 """mro列表是通过一个C3算法得出来的,我们无需明白底层原理,只需要知道每个类的mro列表到底是什么,然后按照这个列表去查找就行""" # 在打印mro列表的时候,一定是从起始类开始 """mro列表,每个类都有自己的mro列表,怎么查看类的mro列表""" a = A() # a.test() print(A.mro()) # (<class '__main__.A'>, <class 'object'>) print(A.__mro__)
6. 鸭子类型
什么是多态? 同一种事物的多种形态 鸭子类型的两种方式 第一种: import abc # # abstract class 抽象类 具体的Specific class Foo(metaclass=abc.ABCMeta): # 把animal类变成了抽象类 @abc.abstractmethod # """父类中得方法不是为了实现逻辑的,实现功能的,而是单纯的为了限制子类的行为""" def func(self): # 把抽象类中得方法变成抽象方法, 它不实现具体的功能,就是单纯的为了限制子类中的方法 print('吃的功能') class Bar(Foo): def func(self): print('qq') class Stary(Foo): def func(self): print('ww') stu = Stary() stu.func() """抽象类和普通类有什么区别? 抽象类只能够被继承、不能够被实例化""" """怎么限制子类Bar类必须有func功能? 我们可以在父类中来限制子类的行为,其实就是限制子类中必须有某些方法""" 第二种 : """Python崇尚的是鸭子类型""" """鸭子类型就是更多的关注的是对象的行为,而不是对象的类型""" 并不是一定要限制子类要实现父类的功能 而是在不继承的情况下 照样能让 其他类有这个功能 class People(): def speak(self):pass def jiao(self): pass class Dog(): def speak(self): pass class Pig(): def speak(self): pass """多态带来的特性:在不考虑对象类型的情况下,直接调用对象的方法或者属性""" def animal(obj): return obj.speak() obj = Pig() obj1 = Dog() animal(obj) animal(obj1)