Python 面向对象 组合-多态与多态性-封装-proper…

2018-08-26 17:30:42来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

面向对象-组合

1.什么是组合

  组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象

 1 class Foo:
 2     xxx = 111
 3 
 4 class Bar:
 5     yyy = 222
 6 
 7 obj = Foo()
 8 obj.attr = Bar()
 9 
10 print(obj.xxx)
11 >>>111
12 print(obj.attr.yyy)
13 >>>222

 

2.为何要用组合

  通过为某一个对象添加属性(属性的值是另外一个类的对象)的方式,可以间接地将两个类关联/整合/组合到一起

  从而减少类与类之间代码冗余

 1 class Foo1:
 2     pass
 3 class Foo2:
 4     pass
 5 class Foo3:
 6     pass
 7 
 8 class Bar:
 9     pass
10 
11 obj_from_bar=Bar()
12 
13 obj1=Foo1()
14 obj2=Foo2()
15 obj3=Foo3()
16 
17 obj1.attr1=obj_from_bar
18 obj2.attr2=obj_from_bar
19 obj3.attr3=obj_from_bar

 

3.如何用组合

 1 class OldboyPeople:
 2     school = 'Oldboy'
 3 
 4     def __init__(self, name, age, sex, ):
 5         self.name = name
 6         self.age = age
 7         self.sex = sex
 8 
 9 
10 class OldboyStudent(OldboyPeople):
11     def __init__(self, name, age, sex, score=0):
12         OldboyPeople.__init__(self, name, age, sex)
13         self.score = score
14         self.courses = []
15 
16     def choose_course(self):
17         print('%s choosing course' % self.name)
18 
19     def tell_all_course(self):
20         print(('学生[%s]选修的课程如下' % self.name).center(50, '='))
21         for obj in self.courses:
22             obj.tell_info()
23         print('=' * 60)
24 
25 
26 class OldboyTeacher(OldboyPeople):
27     def __init__(self, name, age, sex, level):
28         OldboyPeople.__init__(self, name, age, sex)
29         self.level = level
30         self.courses = []
31 
32     def score(self, stu, num):
33         stu.score = num
34 
35     def tell_all_course(self):
36         print(('老师[%s]教授的课程如下' % self.name).center(50, '*'))
37         for obj in self.courses:
38             obj.tell_info()
39         print('*' * 70)
40 
41 
42 class Course:
43     def __init__(self, c_name, c_price, c_period):
44         self.c_name = c_name
45         self.c_price = c_price
46         self.c_period = c_period
47 
48     def tell_info(self):
49         print('<课程名:%s 价钱:%s 周期:%s>' % (self.c_name, self.c_price, self.c_period))
50 
51 
52 # 创建课程对象
53 python = Course('python全栈开发', 1900, '5mons')
54 linux = Course('linux架构师', 900, '3mons')
55 
56 stu1 = OldboyStudent('刘二蛋', 38, 'male')
57 stu1.courses.append(python)
58 stu1.courses.append(linux)
59 stu1.tell_all_course()
60 
61 tea1 = OldboyTeacher('egon', 18, 'male', 10)
62 tea1.courses.append(python)
63 tea1.tell_all_course()

 

面向对象-多态与多态性

1.什么是多态

  多态指的是同一种/类事物的不同形态

2.为何要用多态

  多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象

3.如何用多态

  Animal()  #父类只是用来建立规范的,不能用来实例化,更无需实现内部的方法

 1 import abc
 2 
 3 
 4 class Animal(metaclass=abc.ABCMeta):
 5     @abc.abstractmethod
 6     def speak(self):
 7         pass
 8 
 9     @abc.abstractmethod
10     def run(self):
11         pass
12 
13 
14 
15 class People(Animal):
16     def speak(self):
17         print('say hello')
18 
19     def run(self):
20         pass
21 
22 
23 class Dog(Animal):
24     def speak(self):
25         print('汪汪汪')
26 
27     def run(self):
28         pass
29 
30 
31 class Pig(Animal):
32     def speak(self):
33         print('哼哼哼')
34 
35     def run(self):
36         pass
37 
38 
39 obj1 = People()
40 obj2 = Dog()
41 obj3 = Pig()

Python推崇的是鸭子类型,只要你叫的声音像鸭子,并且你走路的样子也像鸭子,那你就是鸭子

 1 class Disk:
 2     def read(self):
 3         print('Disk read')
 4 
 5     def write(self):
 6         print('Disk write')
 7 
 8 
 9 class Memory:
10     def read(self):
11         print('Mem read')
12 
13     def write(self):
14         print('Mem write')
15 
16 
17 class Cpu:
18     def read(self):
19         print('Cpu read')
20 
21     def write(self):
22         print('Cpu write')
23 
24 
25 obj1 = Disk()
26 obj2 = Memory()
27 obj3 = Cpu()
28 
29 obj1.read()
30 obj2.read()
31 obj3.read()

 

面向对象-封装

1.什么是封装

  装: 往容器/名称空间里存入名字

  封: 代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内

2.为何要封装

  封装数据属性:

    将数据属性隐藏起来,类外就无法直接操作属性,需要类内部开辟一个接口,让外部的使用可以间接地操作属性,可以在接口内定制任意的控制逻辑,从而严格控制使用者对属性的操作

 1 class People:
 2     def __init__(self, name, age):
 3         self.__name = name
 4         self.__age = age
 5 
 6     def tell_info(self):
 7         print('<name:%s age:%s>' % (self.__name, self.__age))
 8 
 9     def set_info(self, name, age):
10         if type(name) is not str:
11             print('名字必须是str类型傻叉')
12             return
13         if type(age) is not int:
14             print('年龄必须是int类型傻叉')
15             return
16         self.__name = name
17         self.__age = age
18 
19 
20 obj = People('egon', 18)
21 obj.set_info('EGON', '18')
22 obj.tell_info()

  封装函数属性: 隔离复杂度

 1 class ATM:
 2     def __card(self):
 3         print('插卡')
 4 
 5     def __auth(self):
 6         print('用户认证')
 7 
 8     def __input(self):
 9         print('输入取款金额')
10 
11     def __print_bill(self):
12         print('打印账单')
13 
14     def __take_money(self):
15         print('取款')
16 
17     def withdraw(self):
18         self.__card()
19         self.__auth()
20         self.__input()
21         self.__print_bill()
22         self.__take_money()
23 
24 
25 a = ATM()
26 a.withdraw()

3.如何封装

  在类内定义的属性前加__开头(没有__结尾)

  总结:

    1. __开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问

    2. 该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形

    3. 如果父类不想让子类覆盖自己的属性,可以在属性前加__开头

 1 class Foo:
 2     def __f1(self):  # _Foo__f1
 3         print('Foo.f1')
 4 
 5     def f2(self):
 6         print('Foo.f2')
 7         self.__f1()  # obj._Foo__f1()
 8 
 9 
10 class Bar(Foo):
11     def __f1(self):  # _Bar__f1
12         print('Bar.f1')
13 
14 
15 obj = Bar()
16 
17 >>>Foo.f2
18 >>>Foo.f1

 

面向对象-property

property装饰器是用来将类内的函数属性伪装成数据属性

 1 class People:
 2     def __init__(self, name):
 3         self.__name = name
 4 
 5     @property
 6     def name(self):
 7         return '<名字:%s>' % self.__name
 8 
 9     @name.setter
10     def name(self, obj):
11         if type(obj) is not str:
12             print('name必须为str类型')
13             return
14         self.__name = obj
15 
16     @name.deleter
17     def name(self):
18         print('不让删')
19 
20 obj = People('egon')
21 del obj.name
22 print(obj.__dict__)

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Python 对象(type/object/class) 作用域 一等函数 (慕课--P

下一篇:MySQL Connector Python