面向对象编程

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

二、面向对象编程介绍:

1.描述

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

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

2.优势(好处)

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

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

类(class)

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

对象(object)

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

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

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

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

封装(Encapsulation 

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

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

继承(Inheritance

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

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

多态(Polymorphism

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

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

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

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

4.补充几点:

(1)接口

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

(2)方法

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

三、示例代码和讲解

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

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 # 定义类
 class Role:
     n = 123                   # 类变量
     name = "我是类name"
     n_list = []
     def __init__(self, name, role, weapon, life_value=100, money=15000):
         # 构造函数
         # 在实例化时做一些类的初始化工作
         self.name = name      # 实例变量(静态属性),作用域就是实例本身
         self.role = role
         self.weapon = weapon
         self.life_value = life_value
         self.money = money

     def shoot(self):            # 类的方法、功能(动态属性)
         print("Shooting...")

     def got_shot(self):
         print("%s : i  got shoot...f**k"%self.name)

     def buy_gun(self,gun_name):
         print("%s buy a %s..."%(self.name, gun_name))

 r1 = Role("zing-p", "Police", "AK47")
 r2 = Role("alex", "terrorist", "B22")
 print(Role.n)        # ---->123        解释:可直接调用类变量
 print(Role.name)     # ---->我是类name
 print(r1.n)          # ---->123
 print(r1.name)       # ---->zing-p     解释:实例变量(静态属性),作用域就是实例本身。所以优先找实例变量,再找类变量
 r1.buy_gun("B22")    # ---->zing-p buy a B22...

 r1.name = "张三"
 print(r1.name)       # ---->张三       解释:可以更改实例变量的值

 r1.bullet_prove = True      # 增加r1这个实例的属性
 print(r1.bullet_prove)      # ---->True   解释:

 r1.n_list.append("r1form")  # 更改了类变量n_list的值
 print(r2.n_list)            # ---->['r1form']

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

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"
 # 定义类
 class Role:

     def __init__(self, name, role, weapon, life_value=100, money=15000):
         # 构造函数
         # 在实例化时做一些类的初始化工作
         self.name = name      # 实例变量(静态属性),作用域就是实例本身
         self.role = role
         self.weapon = weapon
         self.__life_value = life_value # 定义私有属性 类内部可以访问  外部不能访问
         self.money = money

     def show_status(self):
         print("%s: weapon:%s, life_value:%s." % (self.name,
                                                  self.weapon,
                                                  self.__life_value))

     def __del__(self):
         print("%s 所在实例已经被释放了。" % self.name)

     def shoot(self):            # 类的方法、功能(动态属性)
         print("Shooting...")

     def __got_shot(self):       # 私有化方法
         print("%s : i  got shoot...f**k" % self.name)

     def buy_gun(self, gun_name):
         print("%s buy a %s..." % (self.name, gun_name))

 r1 = Role("zing-p", "Police", "AK47")
 r2 = Role("alex", "terrorist", "B22")

 # 运行结果:
 # AttributeError: 'Role' object has no attribute '__life_value'  #说明私有属性不能从外部访问
 # alex 所在实例已经被释放了。
 # zing-p 所在实例已经被释放了。

 # print(r1.name, r1.weapon)
 # print(r2.name, r2.weapon)
 # 运行结果:
 # zing-p AK47
 # alex B22
 # zing-p 所在实例已经被释放了。
 # alex 所在实例已经被释放了。

 # print(r1.name, r1.weapon)
 # del r1
 # print(r2.name, r2.weapon)
 # 运行结果:
 # zing-p AK47
 # zing-p 所在实例已经被释放了。
 # alex B22
 # alex 所在实例已经被释放了。

 # print(r1.show_status())
 # 运行结果:
 # zing-p: weapon:AK47, life_value:100.        # 通过访问内部的方法、这个内部方法调用了私有属性
 # None                                        # show_status()无返回值
 # zing-p 所在实例已经被释放了。               # 析构函数自动执行
 # alex 所在实例已经被释放了。                 # 析构函数自动执行

3.类的继承:

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 # 经典式类写法
 # class People:

 # 新式类写法
 class People(object):
     def __init__(self, name, age):
         self.name = name
         self.age  = age

     def eat(self):
         print("%s is eating...." % self.name)

     def sleep(self):
         print("%s is sleeping..." % self.name)

 class Man(People):
     def __init__(self, name, age, money):
         People.__init__(self, name, age)   # 等价于这么写: super(Man, self).__init__(name, age)
         self.money = money
         print("%s 一出生就有%s $." % (self.name, money))

     def smoke(self):
         print("%s is smoking..." % self.name)

     def sleep(self):
         People.sleep(self)             # 调用父类的sleep方法
         print("Man is sleeping...")    # 对父类中的sleep方法增加功能

 class Women(People):
     def give_birth(self):
         print("%s is given birth a baby." % self.name)

 m1 = Man("zing-p", 25, 10)
 w1 = Women("angelababy", 27)
 m1.eat()
 m1.smoke()
 m1.sleep()
 w1.give_birth()
 # 输出结果:
 # zing-p is eating....     #  继承了父类eat方法
 # zing-p is smoking...     #  自己的smoke方法
 # zing-p is sleeping...
 # Man is sleeping...
 # angelababy is given birth a baby.

4.类的多继承:

  # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 class People(object):
     friends = []
     def __init__(self, name, age):
         self.name = name
         self.age = age

     def eat(self):
         print("%s is eating...." % self.name)

     def sleep(self):
         print("%s is sleeping..." % self.name)

 class Relation(object):
     def makefriends(self,obj):
         print("%s is making friends with %s." % (self.name, obj.name))
         self.friends.append(obj)  # 添加的是一个对象,不应该是obj.name,因为obj.name是个字符串。

 class Man(People, Relation):
     def __init__(self, name, age, money):
         super(Man, self).__init__(name, age)
         self.money = money

     def smok(self):
         print("%s is smoking..." % self.name)

     def sleep(self):
         People.sleep(self)
         print("Man is sleeping...")

 class Women(People, Relation):
     def give_birth(self):
        print("%s is given birth a baby." % self.name)

 m1 = Man("zing-p", 25, 10)
 w1 = Women("angelababy", 27)

 m1.makefriends(w1)
 print(m1.friends[0].name)  # m1.friends[0]其实是w1这个对象实例,具有name属性,即便是W1的name更改后,也会输出更改后的name。

 # 输出结果:
 # zing-p is making friends with angelababy.
 # anglelababy

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

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 # 定义一个School(学校)类
 class School(object):  # object是基类
     def __init__(self, name, addr):
         self.name = name
         self.addr = addr
         self.students = []
         self.staffs = []

     def enroll(self, stu_obj):
         print("为学员%s办理注册手续" % stu_obj.name)
         self.students.append(stu_obj)

     def hire(self, staff_obj):
         print("雇佣新员工:%s。" % (staff_obj.name))
         self.staffs.append(staff_obj)

 # 定义一个SchoolMember(学校成员)类
 class SchoolMember(object):
     def __init__(self, name, age, sex):
         self.name = name
         self.age = age
         self.sex = sex

     def tell(self):
         pass

 # 定义一个Teacher(老师)类,并继承SchoolMember类
 class Teacher(SchoolMember):
     def __init__(self, name, age, sex, salary, course):
         super(Teacher, self).__init__(name, age, sex)
         self.salary = salary
         self.course = course

     def tell(self):
         print('''
         -------Info of Teacher:%s------
         Name:%s
         Age:%s
         Sex:%s
         Salary:%s
         Course:%s
         ''' % (self.name, self.name, self.age, self.sex, self.salary, self.course))

     def teach(self):
         print("%s is teaching %s course" % (self.name, self.course))

 # 定义一个Student(学生)类,并继承SchoolMember类
 class Student(SchoolMember):
     def __init__(self, name, age, sex, stu_id, grade):
         super(Student, self).__init__(name, age, sex)
         self.stu_id = stu_id
         self.grade = grade

     def tell(self):
         print('''
                 -------Info of Student:%s------
                 Name:%s
                 Age:%s
                 Sex:%s
                 Stu_id:%s
                 Grade:%s
                 ''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))

     def pay_tuition(self, tuition_fee):
         print("学生%s交学费:%s$。" % (self.name, tuition_fee))

 school = School("清华大学", "五道口")

 s1 = Student("李小龙", 22, "男", 1001, "大四")
 s2 = Student("杨颖", 18, "女", 1002, "大四")

 t1 = Teacher("张老师", 40, "男", 20000, "高数")
 t2 = Teacher("李老师", 33, "女", 8000, "毛概")

 s1.pay_tuition(5500)              # 学生李小龙交学费:5500$。  # 执行S1这个实例的pay方法
 school.enroll(s1)                 # 为学员李小龙办理注册手续  # 执行school这个实例的enroll方法
 print(school.students[0])         # <__main__.Student object at 0x01D28190> # 执行school这个实例的enroll方法后
                                                                             # 得到一个student列表,列表中装有s1这个实例对象
 print(school.students[0].grade)   # 大四 # school.students[0]是s1实例对象

 t2.teach()                        # 李老师 is teaching 毛概 course
 school.hire(t2)                   # 雇佣新员工:李老师。
 print(school.staffs[0])           # <__main__.Teacher object at 0x01CF81D0>
 

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

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

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 class Animal:
     def __init__(self, name):
         self.name = name

 class Cat(Animal):
     # 猫叫
     def talk(self):
         print("The cat %s is mewing..." % self.name)

 class Dog(Animal):
     # 狗吠
     def talk(self):
         print("The dog %s is barking..." % self.name)

 c = Cat('Missy')
 d = Dog('Lassie')

 #  这样基本能实现“一个接口、多种实现”的效果:
 # def animal_talk(obj):
 #     obj.talk()
 # animal_talk(c)      # The cat Missy is mewing...
 # animal_talk(d)      #The dog Lassie is barking...

6.2再来看看多态:

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 class Animal:
     def __init__(self, name):
         self.name = name

     @staticmethod
     def animal_talk(obj):
         obj.talk()

 class Cat(Animal):
     # 猫叫
     def talk(self):
         print("The cat %s is mewing..." % self.name)

 class Dog(Animal):
     # 狗吠
     def talk(self):
         print("The dog %s is barking..." % self.name)

 c = Cat('Missy')
 d = Dog('Lassie')

 #  这样基本能实现“一个接口、多种实现”的效果:
 # def animal_talk(obj):
 #     obj.talk()
 Animal.animal_talk(c)      # The cat Missy is mewing...
 Animal.animal_talk(d)      # The dog Lassie is barking...
***新式类和经典类区别:类的继承顺序不同。python3.X:经典类和新式类都是按广度优先继承的。python2.X:  经典类:按深度优先来继承的(在python中深度优先效率比广度优先的效率低)。  新式类:按广度优先来继承的。

本节作业: 选课系统


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


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


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. HTTP协议介绍(SERVLET)

    本文是servlet的入门篇,主要简单介绍下http协议 1.什么是HTTP _ 1.http协议:_1. 复杂解释:   http(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议 ...

  2. HDU 4432 Sum of divisors (进制模拟)

    三个小函数 getdiv();        求因子 getsum();     求平方和 change();     转换成该进制 #include <cstdio> #include ...

  3. dvwa+xampp搭建显示乱码的问题:解决办法

    如图,dvwa显示乱码,解决办法有两个:

  4. Spring MVC之messageConverters

    <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案.<mvc:annotation-dri ...

  5. 【设计模式 - 9】之装饰者模式(Decorator)

    1      模式简介 装饰者模式允许向一个现有的对象添加新的功能,同时又不改变其结构. 装饰者模式的思路是用"调料"对象将原始对象进行层层包裹,同时其属性.动作层层传递,达到最终 ...

  6. Memo打印1

              Delphi 打印Memo里面的内容 实现的功能和记事本的打印的功能一样 打印保存为文件时此时的文件名如何设置? 当Memo里的文本数量巨大时 窗体正在打印会出现点数字显示问题 闪 ...

  7. 理解ArcGIS Javascript Viewer Widget及编程模型

    一个ArcGIS Javascript Viewer for JavaScript Widget是一组可以共享.迁移及部署到JavaScript View程序中的的文本文件.通常,一个程序员如果要开发 ...

  8. mysql默认用户名和密码

    默认用户名:root 密码:gree..

  9. Python之路【第五篇】:面向对象和相关

    Python之路[第五篇]:面向对象及相关   面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查是否obj是否 ...

  10. 11.1 afternoon

    幸运数字(number)Time Limit:1000ms Memory Limit:64MB题目描述LYK 最近运气很差,例如在 NOIP 初赛中仅仅考了 90 分,刚刚卡进复赛,于是它决定使用一些 ...