面向对象编程

一、编程范式:编程的方法论。程序员编程的“套路”及“特点”特点总结,抽象成方法、规范。

二、面向对象编程介绍:

1.描述

  世界万物,皆可分类;世间万物,皆为对象;只要是对象,就肯定属于某种品类;只要是对象,就肯定有一定的属性。

  opp编程(面向对象编程)的抽象机制是将待解问题抽象为面向对象的程序中的对象。利用封装使每个对象都拥有个体的身份。程序便是成堆的对象,彼此通过消息的传递,请求其它对象 进行工作。也可以说opp编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述。

2.优势(好处)

  使程序的维护和扩展变简单;使他人更容易理解代码逻辑;大大提高程序开发效率;使他人更容易理解代码逻辑,使团队开发更从容。

3.面向对象有几个特性:

类(class)

  一个类就是对一类具有相同属性的对象的抽象。(可以理解为类型、原型)。类中定义这些对象都具备的属性、共同方法。比如:卡车1,小汽车1,房车1...等对象都具有轮子、方向盘、发动机...等属性和载东西、开动等方法,那么我们可以提取它们的这些属性和方法,抽象出汽车这种“类”。那么凡是汽车都具有轮子、方向盘、发动机...等属性和载东西、开动等方法。

对象(object)

  一个对象即是一个类的实例化后实例,每个对象都是其类中的一个实体(把一个类变成一个具体对象的过程叫实例化)。

  物以类聚——就是说明:类是相似对象的集合。类中的对象可以接受相同的消息。换句话说:类包含和描述了“具有共同特性(数据元素)和共同行为(功能)”的一组对象。

比如:苹果、梨、橘子等等对象都属于水果类。

  一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同。

封装(Encapsulation 

  封装(有时也被称为信息隐藏)就是把数据和行为结合在一个包中,并对对象的使用者隐藏数据的实现过程。信息隐藏是面向对象编程的基本原则,而封装是实现这一原则的一种方 式。

  封装使对象呈现出“黑盒子”特性,这是对象再利用和实现可靠性的关键步骤。也就是说在类中对数据的赋值、内部调用等对外部用户是透明的(不可见的),这使类变成了一个胶囊或容器,里面包含着类的数据和方法。

继承(Inheritance

  继承的思想就是允许在已存在类的基础上构建新的类。一个子类能够继承父类的所有成员,包括属性和方法。

  继承的主要作用:通过实现继承完成代码重用;通过接口继承完成代码被重用。继承是一种规范的技巧,而不是一种实现的技巧。

多态(Polymorphism

  多态是面向对象的重要特性,多态提供了“接口与实现分离”。多态不但能改善程序的组织架构及可读性,更利于开发出“可扩充”的程序。简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
  编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工在九点钟开始工作, 他只要在九点钟的时候说:“开始工作”即可,而不需要对销售人员说:“开始销售工作”,对技术人员说:“开始技术工作”, 因为“员工”是一个抽象的事物, 只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然会各司其职,做各自的工作。
多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定。

  继承是多态的基础。多态是继承的目的。

  合理的运用基于类继承的多态、基于接口继承的多态和基于模版的多态,能增强程序的简洁性、灵活性、可维护性、可重用性和可扩展性。

  面向对象是建立在其他编程技术之上的,是以前的编程思想的自然产物。如果说结构化软件设计是将函数式编程技术应用到命令式语言中进行程序设计,面向对象编程不过是将函数式模型应用到命令式程序中的另一途径,此时,模块进步为对象,过程龟缩到class的成员方法中。OOP的很多技术——抽象数据类型、信息隐藏、接口与实现分离、对象生成功能、消息传递机制等等,很多东西就是结构化软件设计所拥有的、或者在其他编程语言中单独出现。但只有在面向对象语言中,他们才共同出现,以一种独特的合作方式互相协作、互相补充。

4.补充几点:

(1)接口

  每个对象都有接口。接口不是类,而是对符合接口需求的类所作的一套规范。接口说明类应该做什么但不指定如何作的方法。一个类可以有一个或多个接口。

(2)方法

  方法决定了某个对象究竟能够接受什么样的消息。面向对象的设计有时也会简单地归纳为“将消息发送给对象”。

三、示例代码和讲解

1.类语法、属性、方法、类变量、实例变量:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = "ZingP"
  3.  
  4. # 定义类
  5. class Role:
  6. n = 123 # 类变量
  7. name = "我是类name"
  8. n_list = []
  9. def __init__(self, name, role, weapon, life_value=100, money=15000):
  10. # 构造函数
  11. # 在实例化时做一些类的初始化工作
  12. self.name = name # 实例变量(静态属性),作用域就是实例本身
  13. self.role = role
  14. self.weapon = weapon
  15. self.life_value = life_value
  16. self.money = money
  17.  
  18. def shoot(self): # 类的方法、功能(动态属性)
  19. print("Shooting...")
  20.  
  21. def got_shot(self):
  22. print("%s : i got shoot...f**k"%self.name)
  23.  
  24. def buy_gun(self,gun_name):
  25. print("%s buy a %s..."%(self.name, gun_name))
  26.  
  27. r1 = Role("zing-p", "Police", "AK47")
  28. r2 = Role("alex", "terrorist", "B22")
  29. print(Role.n) # ---->123 解释:可直接调用类变量
  30. print(Role.name) # ---->我是类name
  31. print(r1.n) # ---->123
  32. print(r1.name) # ---->zing-p 解释:实例变量(静态属性),作用域就是实例本身。所以优先找实例变量,再找类变量
  33. r1.buy_gun("B22") # ---->zing-p buy a B22...
  34.  
  35. r1.name = "张三"
  36. print(r1.name) # ---->张三 解释:可以更改实例变量的值
  37.  
  38. r1.bullet_prove = True # 增加r1这个实例的属性
  39. print(r1.bullet_prove) # ---->True 解释:
  40.  
  41. r1.n_list.append("r1form") # 更改了类变量n_list的值
  42. print(r2.n_list) # ---->['r1form']

2.析构函数、私有属性、私有方法示例:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = "ZingP"
  3. # 定义类
  4. class Role:
  5.  
  6. def __init__(self, name, role, weapon, life_value=100, money=15000):
  7. # 构造函数
  8. # 在实例化时做一些类的初始化工作
  9. self.name = name # 实例变量(静态属性),作用域就是实例本身
  10. self.role = role
  11. self.weapon = weapon
  12. self.__life_value = life_value # 定义私有属性 类内部可以访问 外部不能访问
  13. self.money = money
  14.  
  15. def show_status(self):
  16. print("%s: weapon:%s, life_value:%s." % (self.name,
  17. self.weapon,
  18. self.__life_value))
  19.  
  20. def __del__(self):
  21. print("%s 所在实例已经被释放了。" % self.name)
  22.  
  23. def shoot(self): # 类的方法、功能(动态属性)
  24. print("Shooting...")
  25.  
  26. def __got_shot(self): # 私有化方法
  27. print("%s : i got shoot...f**k" % self.name)
  28.  
  29. def buy_gun(self, gun_name):
  30. print("%s buy a %s..." % (self.name, gun_name))
  31.  
  32. r1 = Role("zing-p", "Police", "AK47")
  33. r2 = Role("alex", "terrorist", "B22")
  34.  
  35. # 运行结果:
  36. # AttributeError: 'Role' object has no attribute '__life_value' #说明私有属性不能从外部访问
  37. # alex 所在实例已经被释放了。
  38. # zing-p 所在实例已经被释放了。
  39.  
  40. # print(r1.name, r1.weapon)
  41. # print(r2.name, r2.weapon)
  42. # 运行结果:
  43. # zing-p AK47
  44. # alex B22
  45. # zing-p 所在实例已经被释放了。
  46. # alex 所在实例已经被释放了。
  47.  
  48. # print(r1.name, r1.weapon)
  49. # del r1
  50. # print(r2.name, r2.weapon)
  51. # 运行结果:
  52. # zing-p AK47
  53. # zing-p 所在实例已经被释放了。
  54. # alex B22
  55. # alex 所在实例已经被释放了。
  56.  
  57. # print(r1.show_status())
  58. # 运行结果:
  59. # zing-p: weapon:AK47, life_value:100. # 通过访问内部的方法、这个内部方法调用了私有属性
  60. # None # show_status()无返回值
  61. # zing-p 所在实例已经被释放了。 # 析构函数自动执行
  62. # alex 所在实例已经被释放了。 # 析构函数自动执行

3.类的继承:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = "ZingP"
  3.  
  4. # 经典式类写法
  5. # class People:
  6.  
  7. # 新式类写法
  8. class People(object):
  9. def __init__(self, name, age):
  10. self.name = name
  11. self.age = age
  12.  
  13. def eat(self):
  14. print("%s is eating...." % self.name)
  15.  
  16. def sleep(self):
  17. print("%s is sleeping..." % self.name)
  18.  
  19. class Man(People):
  20. def __init__(self, name, age, money):
  21. People.__init__(self, name, age) # 等价于这么写: super(Man, self).__init__(name, age)
  22. self.money = money
  23. print("%s 一出生就有%s $." % (self.name, money))
  24.  
  25. def smoke(self):
  26. print("%s is smoking..." % self.name)
  27.  
  28. def sleep(self):
  29. People.sleep(self) # 调用父类的sleep方法
  30. print("Man is sleeping...") # 对父类中的sleep方法增加功能
  31.  
  32. class Women(People):
  33. def give_birth(self):
  34. print("%s is given birth a baby." % self.name)
  35.  
  36. m1 = Man("zing-p", 25, 10)
  37. w1 = Women("angelababy", 27)
  38. m1.eat()
  39. m1.smoke()
  40. m1.sleep()
  41. w1.give_birth()
  42. # 输出结果:
  43. # zing-p is eating.... # 继承了父类eat方法
  44. # zing-p is smoking... # 自己的smoke方法
  45. # zing-p is sleeping...
  46. # Man is sleeping...
  47. # angelababy is given birth a baby.

4.类的多继承:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = "ZingP"
  3.  
  4. class People(object):
  5. friends = []
  6. def __init__(self, name, age):
  7. self.name = name
  8. self.age = age
  9.  
  10. def eat(self):
  11. print("%s is eating...." % self.name)
  12.  
  13. def sleep(self):
  14. print("%s is sleeping..." % self.name)
  15.  
  16. class Relation(object):
  17. def makefriends(self,obj):
  18. print("%s is making friends with %s." % (self.name, obj.name))
  19. self.friends.append(obj) # 添加的是一个对象,不应该是obj.name,因为obj.name是个字符串。
  20.  
  21. class Man(People, Relation):
  22. def __init__(self, name, age, money):
  23. super(Man, self).__init__(name, age)
  24. self.money = money
  25.  
  26. def smok(self):
  27. print("%s is smoking..." % self.name)
  28.  
  29. def sleep(self):
  30. People.sleep(self)
  31. print("Man is sleeping...")
  32.  
  33. class Women(People, Relation):
  34. def give_birth(self):
  35. print("%s is given birth a baby." % self.name)
  36.  
  37. m1 = Man("zing-p", 25, 10)
  38. w1 = Women("angelababy", 27)
  39.  
  40. m1.makefriends(w1)
  41. print(m1.friends[0].name) # m1.friends[0]其实是w1这个对象实例,具有name属性,即便是W1的name更改后,也会输出更改后的name。
  42.  
  43. # 输出结果:
  44. # zing-p is making friends with angelababy.
  45. # anglelababy

5.类的继承及类的相互关联:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = "ZingP"
  3.  
  4. # 定义一个School(学校)类
  5. class School(object): # object是基类
  6. def __init__(self, name, addr):
  7. self.name = name
  8. self.addr = addr
  9. self.students = []
  10. self.staffs = []
  11.  
  12. def enroll(self, stu_obj):
  13. print("为学员%s办理注册手续" % stu_obj.name)
  14. self.students.append(stu_obj)
  15.  
  16. def hire(self, staff_obj):
  17. print("雇佣新员工:%s。" % (staff_obj.name))
  18. self.staffs.append(staff_obj)
  19.  
  20. # 定义一个SchoolMember(学校成员)类
  21. class SchoolMember(object):
  22. def __init__(self, name, age, sex):
  23. self.name = name
  24. self.age = age
  25. self.sex = sex
  26.  
  27. def tell(self):
  28. pass
  29.  
  30. # 定义一个Teacher(老师)类,并继承SchoolMember类
  31. class Teacher(SchoolMember):
  32. def __init__(self, name, age, sex, salary, course):
  33. super(Teacher, self).__init__(name, age, sex)
  34. self.salary = salary
  35. self.course = course
  36.  
  37. def tell(self):
  38. print('''
  39. -------Info of Teacher:%s------
  40. Name:%s
  41. Age:%s
  42. Sex:%s
  43. Salary:%s
  44. Course:%s
  45. ''' % (self.name, self.name, self.age, self.sex, self.salary, self.course))
  46.  
  47. def teach(self):
  48. print("%s is teaching %s course" % (self.name, self.course))
  49.  
  50. # 定义一个Student(学生)类,并继承SchoolMember类
  51. class Student(SchoolMember):
  52. def __init__(self, name, age, sex, stu_id, grade):
  53. super(Student, self).__init__(name, age, sex)
  54. self.stu_id = stu_id
  55. self.grade = grade
  56.  
  57. def tell(self):
  58. print('''
  59. -------Info of Student:%s------
  60. Name:%s
  61. Age:%s
  62. Sex:%s
  63. Stu_id:%s
  64. Grade:%s
  65. ''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))
  66.  
  67. def pay_tuition(self, tuition_fee):
  68. print("学生%s交学费:%s$。" % (self.name, tuition_fee))
  69.  
  70. school = School("清华大学", "五道口")
  71.  
  72. s1 = Student("李小龙", 22, "男", 1001, "大四")
  73. s2 = Student("杨颖", 18, "女", 1002, "大四")
  74.  
  75. t1 = Teacher("张老师", 40, "男", 20000, "高数")
  76. t2 = Teacher("李老师", 33, "女", 8000, "毛概")
  77.  
  78. s1.pay_tuition(5500) # 学生李小龙交学费:5500$。 # 执行S1这个实例的pay方法
  79. school.enroll(s1) # 为学员李小龙办理注册手续 # 执行school这个实例的enroll方法
  80. print(school.students[0]) # <__main__.Student object at 0x01D28190> # 执行school这个实例的enroll方法后
  81. # 得到一个student列表,列表中装有s1这个实例对象
  82. print(school.students[0].grade) # 大四 # school.students[0]是s1实例对象
  83.  
  84. t2.teach() # 李老师 is teaching 毛概 course
  85. school.hire(t2) # 雇佣新员工:李老师。
  86. print(school.staffs[0]) # <__main__.Teacher object at 0x01CF81D0>

6.多态(一定要记住“一个接口多种实现”)

6.1我们先看“一个接口多种实现”的一种实现方法:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = "ZingP"
  3.  
  4. class Animal:
  5. def __init__(self, name):
  6. self.name = name
  7.  
  8. class Cat(Animal):
  9. # 猫叫
  10. def talk(self):
  11. print("The cat %s is mewing..." % self.name)
  12.  
  13. class Dog(Animal):
  14. # 狗吠
  15. def talk(self):
  16. print("The dog %s is barking..." % self.name)
  17.  
  18. c = Cat('Missy')
  19. d = Dog('Lassie')
  20.  
  21. # 这样基本能实现“一个接口、多种实现”的效果:
  22. # def animal_talk(obj):
  23. # obj.talk()
  24. # animal_talk(c) # The cat Missy is mewing...
  25. # animal_talk(d) #The dog Lassie is barking...

6.2再来看看多态:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = "ZingP"
  3.  
  4. class Animal:
  5. def __init__(self, name):
  6. self.name = name
  7.  
  8. @staticmethod
  9. def animal_talk(obj):
  10. obj.talk()
  11.  
  12. class Cat(Animal):
  13. # 猫叫
  14. def talk(self):
  15. print("The cat %s is mewing..." % self.name)
  16.  
  17. class Dog(Animal):
  18. # 狗吠
  19. def talk(self):
  20. print("The dog %s is barking..." % self.name)
  21.  
  22. c = Cat('Missy')
  23. d = Dog('Lassie')
  24.  
  25. # 这样基本能实现“一个接口、多种实现”的效果:
  26. # def animal_talk(obj):
  27. # obj.talk()
  28. Animal.animal_talk(c) # The cat Missy is mewing...
  29. Animal.animal_talk(d) # The dog Lassie is barking...
  1. ***新式类和经典类区别:类的继承顺序不同。python3.X:经典类和新式类都是按广度优先继承的。python2.X:  经典类:按深度优先来继承的(在python中深度优先效率比广度优先的效率低)。  新式类:按广度优先来继承的。

本节作业: 选课系统

  1.  

角色:学校、学员、课程、讲师
要求:
1. 创建北京、上海 2 所学校
2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,通过学校创建课程 
4. 通过学校创建班级, 班级关联课程、讲师
5. 创建学员时,选择学校,关联班级
6. 创建讲师角色时要关联学校, 
7. 提供两个角色接口
7.1 学员视图, 可以注册, 交学费, 选择班级,
7.2 讲师视图, 讲师可管理自己的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩 
7.3 管理视图,创建讲师, 创建班级,创建课程

  1.  

8. 上面的操作产生的数据都通过pickle序列化保存到文件里

  1.  

python【第六篇】面向对象编程的更多相关文章

  1. python笔记 - day7-1 之面向对象编程

    python笔记 - day7-1 之面向对象编程 什么时候用面向对象: 多个函数的参数相同: 当某一些函数具有相同参数时,可以使用面向对象的方式,将参数值一次性的封装到对象,以后去对象中取值即可: ...

  2. Python 第六篇(中):面向对象编程中级篇

    面向对象编程中级篇: 编程思想概述: 面向过程:根据业务逻辑从上到下写垒代码  #最low,淘汰 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 #混口饭吃 def add(ho ...

  3. Python 第六篇(上):面向对象编程初级篇

    面向:过程.函数.对象: 面向过程:根据业务逻辑从上到下写垒代码! 面向过程的编程弊:每次调用的时候都的重写,代码特别长,代码重用性没有,每次增加新功能所有的代码都的修改!那有什么办法解决上面出现的弊 ...

  4. 那些年被我坑过的Python——玄而又玄(第六章 面向对象编程基础)

    面向对象编程: 面向对象顾名思义,就是把组织代码的粒度从函数级别抽象到对象级别,对象是通过类来生成的,类可以想象为模板或进本框架而对象是在原有模板或框架的基础上增加详细信息的实体,类,有分类.聚类的含 ...

  5. 洗礼灵魂,修炼python(31)--面向对象编程(1)—面向对象,对象,类的了解

    面向对象 1.什么是面向对象 (图片来自网络) 哈哈,当然不是图中的意思. 1).面向对象(Object Oriented,OO)是软件开发方法.利用各大搜索引擎得到的解释都太官方,完全看不懂啥意思对 ...

  6. 洗礼灵魂,修炼python(40)--面向对象编程(10)—定制魔法方法+time模块

    定制魔法方法 1.什么是定制魔法方法 首先定制是什么意思呢?其实就是自定义了,根据我们想要的要求来自定义.而在python中,其实那些所谓的内置函数,内置方法,内置属性之类的其实也是自定义出来的,不过 ...

  7. Python第六章 面向对象

    第六章 面向对象 1.面向对象初了解 ​ 面向对象的优点: ​ 1.对相似功能的函数,同一个业务下的函数进行归类,分类 ​ 2.类是一个公共的模板,对象就是从具体的模板中实例化出来的,得到对象就得到一 ...

  8. Python(六)面向对象、异常处理、反射、单例模式

    本章内容: 创建类和对象 面向对象三大特性(封装.继承.多态) 类的成员(字段.方法.属性) 类成员的修饰符(公有.私有) 类的特殊成员 isinstance(obj, cls) & issu ...

  9. python 学习笔记7 面向对象编程

    一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." ...

  10. 洗礼灵魂,修炼python(34)--面向对象编程(4)—继承

    前面已经说到面向对象编程有封装,继承,多态三大特性,那么其中的继承则很重要,可以直接单独的拿出来解析 继承 1.什么是继承: 字面意是子女继承父母的家产或者特性等.而在编程里继承是指子类继承父类(基类 ...

随机推荐

  1. Django路由系统

    django路由系统 简而言之,django的路由系统作用就是使views里面处理数据的函数与请求的url建立映射关系.使请求到来之后,根据urls.py里的关系条目,去查找到与请求对应的处理方法,从 ...

  2. Validate XML using a XSD (XML Schema)

    Consider this XML file howto.xml : <?xml version="1.0" encoding="ISO-8859-1"? ...

  3. Parallel.Foreach的全部知识要点【转】

    简介 当需要为多核机器进行优化的时候,最好先检查下你的程序是否有处理能够分割开来进行并行处理.(例如,有一个巨大的数据集合,其中的元素需要一个一个进行彼此独立的耗时计算). .net framewor ...

  4. C# SQL 整表插入 分类: C# 2014-09-17 16:18 369人阅读 评论(2) 收藏

    说明: (1)表A的一部分数据插入到表B (2)DataAccess 类,是放在DAL层下的底层类; da.StrConnection 写在DataAccess类中; //整表插入方法 private ...

  5. boost------asio库的使用2(Boost程序库完全开发指南)读书笔记

    网络通信 asio库支持TCP.UDP.ICMP通信协议,它在名字空间boost::asio::ip里提供了大量的网络通信方面的函数和类,很好地封装了原始的Berkeley Socket Api,展现 ...

  6. mysql内核源代码深度解析 缓冲池 buffer pool 整体概述

    http://blog.csdn.net/cjcl99/article/details/51063078

  7. Qt 学习之路 :文本文件读写

    上一章我们介绍了有关二进制文件的读写.二进制文件比较小巧,却不是人可读的格式.而文本文件是一种人可读的文件.为了操作这种文件,我们需要使用QTextStream类.QTextStream和QDataS ...

  8. SQL PL基本概念

    --声明变量 --1.语法: --declare <varible-name> <data-type> <default-constant>默认不变 --decla ...

  9. 一次利用MSSQL的SA账户提权获取服务器权限

    遇到小人,把服务器整走了 自己手里只有sql server的sa账号密码 模糊记起之前用这个账户提权读取文件的事 百度之,发现相关信息一堆堆 各种工具也用了不少 发现不是语法错误就是权限不够 无奈之下 ...

  10. 借用Toad 生成表空间的使用量图示

    图示产生方法 图示(tablespace uage)如下