编程范式概述:
面向过程 和 面向对象 以及函数式编程
面向过程:(Procedure Oriented)是一种以事件为中心的编程思想。
就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。(即执行有先后顺序)
需要纵观全局,对每一个环节知根知底,每个步骤之间联系非常紧密。 支持面向过程的程序设计语言有:C语言 C++ Python等
面向对象:(Object Oriented,简称:OO)是一种以事务为中心的编程思想。
面向对象是把整体分为多个环节,对每个环节单独分析解决,最后整合到一起。 支持面向对象的程序设计语言有C++、Java、C#、Python等。
术语:面向对象的程序设计(Object Oriented Programming,简称为OOP )
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

举例对比面向过程 和 面向对象: 例如汽车!
区别:
“面向过程”的话:汽车启动是一个事件,汽车到站是另一个事件。
编程的时候我们关心的是:某一个事件,而不是汽车本身。
然后分别对启动和到站编写程序,类似的还有修理等等。
“面向对象”则是:需要建立一个汽车的实体,由实体引发事件。
编程的时候我们关心的是:由汽车抽象成的对象,这个对象有自己的属性,像发动机:型号,马力,产地等;
有自己的方法,像启动,行驶等;方法也就是汽车的行为,而不是汽车的每个事件。

联系:
“面向过程”其实是最为实际的一种思考方式;就算是面向对象的方法,也含有面向过程的思想。
可以说面向过程是一种基础的方法,它考虑的是实际功能的实现。一般的面向过程是从上往下步步求进,所以面向过程最重要的是模块化的思想方法。
而“面向对象”的方法主要是把事物给对象化,对象包括属性与行为。
当程序规模不是很大时,“面向过程”的方法还会体现出一种优势,因为程序的流程很清楚,按着模块与函数的方法可以很好的组织。
但是,当程序规模较大的时候,“面向对象”的方法优势就会明显的体现出来:具有程序结构清晰,实现简单,
可有效地减少程序的维护工作量,代码重用率高,软件开发效率高等优点。

另一个通俗的例子:印刷术
面向过程:传统的雕版印刷,把整个板子刻满字,每次印都要刻一块
面向对象:毕昇的活字印刷,把每个字分别雕好,用的时候拼到一起
因为面向过程的联系紧密,单个步骤出错对整体影响比较大,比如整本书需要雕10块木板,结果雕错一个字,一整块木板都要扔掉重新刻。

实例:用函数式编程的方式 实现打印输出如下内容:

小明,10岁,男,上山去砍柴
小明,10岁,男,开车去东北
小明,10岁,男,最爱打游戏
老李,90岁,男,上山去砍柴
老李,90岁,男,开车去东北
老李,90岁,男,最爱打游戏
def foo (name,age,gender,content):
print(name,age,gender,content)
foo("小明","10岁","男","上山去砍柴")
foo("小明","10岁","男","开车去东北")
foo("小明","10岁","男","最爱打游戏") foo("老李","50岁","男","上山去砍柴")
foo("老李","50岁","男","开车去东北")
foo("老李","50岁","男","最爱打游戏")
#===========>>> 上边写法的不足: 参数调用 存在问题
#将上方的实例 改写成面向对象
class Bar:
def foo(self,name,age,gender,content):
print(self,name,age,gender,content)
obj = Bar()
obj.foo("小明","10岁","男","上山去砍柴")
obj.foo("小明","10岁","男","开车去东北")
obj.foo("小明","10岁","男","最爱打游戏")
#输出结果:其中,self 生成的了引用对象地址
#<__main__.Bar object at 0x0000000000705320> 小明 10岁 男 上山去砍柴
#<__main__.Bar object at 0x0000000000705320> 小明 10岁 男 开车去东北
#<__main__.Bar object at 0x0000000000705320> 小明 10岁 男 最爱打游戏
#上方改成了面向对象的方式 但是参数的传递 不够简洁 待优化!

一 定义:
函数:
def + 函数名(参数)
面向对象:
class 类=>> 上方名字叫Bar类
def 方法=>> 上方实例中叫foo
### self 此处必须写。 代指:调用方法的对象(中间人)这个参数是Python自动传递的。
二 执行:
函数:
函数名(参数)
面向对象:
obj = Bar() # 相当于创建了中间人,这个中间人就是一个对象。
obj.foo

理解方法中的self参数:
(1)当程序执行到obj = Bar()的时候,解释器会根据类名Bar()创建了一个中间人(对象),我们可以理解为是:对象应用了类
(2)当中间人(对象)obj执行.foo方法的时候,首先根据上方关联的类名查找.foo方法 然后执行foo方法。
(3)foo中的self 必须写,代指:调用方法的对象(中间人)该参数是Python自动传递的;执行之后,self输出结果,生成的是一个对象引用地址。
(4)中间人(对象)中可以添加参数,即:可以进行值传递。

self 代指:执行当前方法的对象!

而这个‘当前’需要另外注意:在涉及到继承关系的时候,无论对象是调用执行当前类中的方法,还是继承调用父类中的方法,self都是代指外部最开始调用相应方法的对象!

# 实例:理解方法中的self

class Bar:
def foo(self,arg):
print(self,self.name,self.age,arg) zhong_obj1 = Bar() # 中间人(对象1)
zhong_obj1.name = 'jesson' # 说明:中间人(对象)中可以带值 当作参数传递给类里边方法中的self
zhong_obj1.age = '' # 说明:中间人(对象)中可以带有多个值 当作参数传递
zhong_obj1.foo(888) zhong_obj2 = Bar() # 中间人(对象2) 说明:同一个类 可以被多个对象引用
zhong_obj2.name = 'pitter'
zhong_obj2.age = ''
zhong_obj2.foo(666) # 输出结果:
# <__main__.Bar object at 0x0000000000A65390> jesson 25 888
# <__main__.Bar object at 0x0000000000A65400> pitter 20 666

# 优化上方 面向对象改写的实例 [给对象存放值 当作参数传递]

#优化一
class Bar:
def foo(self,contnt):
print(obj.name,obj.age,obj.gender,contnt)
obj = Bar()
obj.name = '小明'
obj.age = 10
obj.gender = '男' obj.foo("上山去砍柴")
obj.foo("开车去东北")
obj.foo("最爱打游戏")

上方的优化 已经基本符合要求
但是还不够简洁 Python这个时候 提供了一种方式,即:构造方法 __init__() 用来封装相关对象默认字段的值

构造方法: 类名后边加括号 自动执行__init__方法   (即:实例化对象的时候,就会执行__init__方法)
特殊作用: [初始化] 用来存放一些默认字段
obj = 类名()
(1)创建对象
(2)通过对象执行类中的一个方法

#采用 构造方法__init__() 对上述实例进一步优化:
class Bar:
def __init__(self,n,a,g):
self.name = n
self.age = a
self.gender = g
def foo(self,contnt):
print(self.name,self.age,self.gender,contnt) obj = Bar("小明",10,"男") obj.foo("上山去砍柴")
obj.foo("开车去东北")
obj.foo("最爱打游戏")

小结:
通过上述实例的优化对比,可以看出,如果使用函数式编程,
需要在每次执行函数时传入相同的参数,如果参数多的话,又需要粘贴复制了..;
而对于面向对象只需要在创建对象时,将所有需要的参数封装到当前对象中,
之后再次使用时,通过self间接去当前对象中取值即可。

面向对象适用场景:
如果多个函数中有一些相同参数时,转换成面向对象。
面向对象的三大特性:
面向对象的三大特性是指:封装、继承和多态。

一、封装
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
所以,在使用面向对象的封装特性时,需要:
将内容封装到某处
从某处调用被封装的内容

二、继承
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

# 基本用法:
class 父类:
def 父类中的方法(self): class 子类(父类):
pass son = 子类()
son.父类中的方法()

实例:

class Father:
def f1(self):
print('Father.f1')
def f2(self):
print('Father.f2')
class Son(Father):
def s1(self):
print('Son.s1')
obj = Son()
obj.s1()
obj.f1()
# 输出结果:
# Son.s1
# Father.f1 # 继承了父类 调用执行父类中的f1方法。

我们知道 如果子类继承了父类 则可以调用父类中的所有方法
那 我们可不可以 调用的时候 不去继承执行父类的方法 而指定执行自己内部的方法呢?
答案:肯定是可以的!

情况1: 不执行父类的方法 执行自己的同名方法
在本地重写和父类中同名的方法 即:在自己内部写一个同名的方法:f2

实例:
class Father:
def f1(self):
print('Father.f1')
def f2(self):
print('Father.f2')
class Son(Father):
def s1(self):
print('Son.s1')
def f2(self):
print('Son.f2')
obj = Son()
obj.s1() # 输出结果:Son.s1
obj.f2() # 输出结果:Son.f2

# 情况2: 即可以执行父类的方法 同时也可以执行自己的同名方法
# 这里可以调用Python内置方法 super()

# 实例:
class Father:
def f1(self):
print('Father.f1')
def f2(self):
print('Father.f2')
class Son(Father):
def s1(self):
print('Son.s1')
def f2(self):
# 方式一
super(Son,self).f2()
# 方式二
Father.f2(self)
print('Son.f2')
obj = Son() # 输出结果:Son.s1
obj.s1() # 输出结果:Father.f2
obj.f2() # 输出结果:Son.f2

# *重点* 多继承的查找顺序# 先来看实例:
# 情况1:
# 子类继承两个父类 两个父类中都有子类调用的方法 该如何继承?

补充注意:子类继承多个父类的写法,即支持多继承!在C++和Python中是支持的,但 在C#和Java中,是不支持的,他们为了避免继承混淆,通常只支持子类继承一个父类的写法!

class Father1:
def a(self):
print('Father1.a')
class Father2:
def a(self):
print('Father2.a') class Son(Father2,Father1):
pass
obj = Son()
obj.a()
# 输出结果:说明:这种情况下 从左往右继承
# Father2.a

结论:

情况2
子类Son继承两个父类 其中一个父类Father1没有该子类调用的方法
而该父类又继承了别的类Grand Grand类中有子类Son调用的方法 然而另一个父类Father2中,也有该子类Son调用的方法,
此时 是找完Father1没找到,继续往上层Grand里边找,还是返回到另一个父类Father2中找? 该如何继承?
看图:

class Grand:
def a(self):
#def b(self): #如果将a方法改成b 则会返回父类Father2中查找方法a
print('Grand.a')
class Father1(Grand):
def b(self):
print('Father1.b')
class Father2:
def a(self):
print('Father2.a') class Son(Father1,Father2):
pass
obj = Son()
obj.a()
# 输出结果:结论:这种情况下 先从左往右继承Father1,发现找不到方法a,继续往上层找,如果还找不到,就返回到另一个父类Father2中查找。
# Grand.a

#情况三

#看图:

Python继承调用顺序        总结:【以下两个结论是在Python3环境下,得出的,也就是针对新式类而言!!!】

情况1:

    如果没有共同的基类(即:继承结构顶部没有交集),那么继承调用的时候,默认按照子类括号中的继承顺序,优先从左往右找,继承第一个父类,然后‘一条路走到黑’(即:一直往下找,找不到相应方法,才会返回来走第二个父类);

情况2:

    如果有共同的基类(即:继承结构顶部有交集),那么子类调用父类方法的时候,首先,默认还是按照括号中的继承顺序,从左往右找,如果父类中没有,父类的父类中也没有,而子类继承的右边第二个父类方法中有相应的方法,此时即使顶部交集的基类中有相应的方法,也不会继承调用基类,而是会返回来优先继承第二个父类中的方法;如果第二个父类方法中,没有相应的方法,则会像情况1那样,继承调用基类中的方法。简单来记,就是,子类继承父类的时候,如果继承结构顶部有交集,存在共同的base基类,那么base基类中的方法,被调用的优先级最低!

补充说明:Python面向对象,继承多个父类调用的时候,永远要清楚,调用方法的self到底代指的对象是谁!当遇到特殊情况,比如,子类对象son_obj继承调用父类中的方法func1,而父类中的该方法func1又调用指定了其他的方法func2,这个时候就要注意了,此时的self还是子类的那个对象,而不是说现在调用执行了父类中的方法func1,self就变成父类的对象;因此,此时即使父类中本身就有方法func2,子类也不一定会继承,因为此时的self对象仍旧是子类的son_obj对象;而是会这样执行,子类优先查找右边的第二父类中是否有相应的方法func2,有的话继承调用,没有的话,才会继承刚才父类中本身自带的方法func2!

经典类(继承 从左往右,深度优先)

新式类(继承 从左往右,广度优先)

对于Python3中全是新式类。 

对于Python2中有新式类和经典类之分,创建类的时候如果继承了(object)那么该类就是新式类;没有继承的话,则是经典类。

这里并不矛盾,上述结论同样适用于Python2,因为,Python创建新式类需要继承(object),这就相当于结论2中多个父类的顶部,有共同的基类,这种情况下遵循广度优先(即:新式类);而对于经典类,继承多个父类的顶部并没有交集,那么这个时候,就是一条路走到黑,深度优先。

结论:Python3虽然都是新式类了,继承的算法是基于C#算法,但是和Python2的继承规则实际上是完全吻合的。

另外,虽然我们暂时搞明白多个继承的调用顺序了,但是,复杂的多层父类继承编程方式,是不提倡的,这样可能会降低Python代码的整体执行效率。

# 多态

可以理解成:

例如:一个类为class A(name,age):

然后实例化的时候,student1 = A('jesson',22)

student2 = A('Tim',20)

这个时候,对象实例化的时候,由于传递的参数不同,实例化之后的对象是不同的。 可样,可以简单的理解成面向对象的多态。

体现:子类可以继承父类的方法,也可以调用自己的方法。

多态:http://www.cnblogs.com/hai-ping/articles/2807750.html

												

Python 面向对象 基础的更多相关文章

  1. python面向对象基础

    面向对象基础 1. 简述 编程方式: 面向过程: 根据代码在脚本的堆叠顺序,从上到下依次执行 函数式编程:将相同功能的代码封装到函数中,直接调用即可,减少代码重复性 面向对象:对函数进行分类和封装,将 ...

  2. Python 面向对象基础知识

    面向对象基础知识 1.什么是面向对象编程? - 以前使用函数 - 类 + 对象 2.什么是类什么是对象,又有什么关系? class 类: def 函数1(): pass def 函数2(): pass ...

  3. python 面向对象基础和高级复习

    面向对象基础 面向对象编程 面向过程编程:类似于工厂的流水线 优点:逻辑清晰 缺点:扩展性差 面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互 优点:扩展性强 缺点: ...

  4. 十六、python面向对象基础篇

    面向对象基础: 在了解面向对象之前,先了解下变成范式: 编程范式是一类典型的编程风格,是一种方法学 编程范式决定了程序员对程序执行的看法 oop中,程序是一系列对象的相互作用 python支持多种编程 ...

  5. 1.Python面向对象基础

    面向对象(OOP) 面向对象编程--object oriented programming 简写 OOP   面向过程和面向对象的区别: 面向过程: 1.把完成某一个需求的所有步骤从头到尾逐步实现 2 ...

  6. [python面向对象]--基础篇

    1.#类 #类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 #定义一个类 class bar: def foo(self,agr): print(self,agr) obj = bar() ...

  7. Python面向对象基础:编码细节和注意事项

    在前面,我用了3篇文章解释python的面向对象: 面向对象:从代码复用开始 面向对象:设置对象属性 类和对象的名称空间 本篇是第4篇,用一个完整的示例来解释面向对象的一些细节. 例子的模型是父类Em ...

  8. Python面向对象基础一

    公司可能过一两个月就要从深圳搬到东莞松山湖,项目组的现在有的在转Java或其他语言的,问我们要不要转java+hoodap+spark方向,我还是先不转,毕竟之前是从ios转回C#,这现在在转其他的那 ...

  9. python面向对象基础-01

    面向对象(OOP)基本概念 前言 话说三国时期曹军于官渡大败袁绍,酒席之间,曹操诗兴大发,吟道:喝酒唱歌,人生真爽! 众将直呼:"丞相好诗",于是命印刷工匠刻板印刷以流传天下; 待 ...

随机推荐

  1. 虚拟机VMware与主机共享文件介绍

    我们经常会在Windows平台安装虚拟机VMware,不管是出于实验测试还是工作需要,伴随而来的就是经常需要在Windows系统和虚拟机系统之间进行共享数据文件,例如,需要将Window主机上的Ora ...

  2. SQL Server修改数据库对象所有者(Owner)浅析

    在SQL Server数据库中如何修改数据库对象(表.视图.存储过程..)的所有者(Owner)呢?一般我们可以使用系统提供的系统存储过程sp_changeobjectowner来修改. 我们先看看s ...

  3. SQL SERVER中的OLEDB等待事件

    OLEDB等待事件介绍 OLEDB等待类型是SQL SERVER 数据库中最常见的几种等待类型之一.它意味着某个会话(SPID)通过SQL Server Native Client OLEDB Pro ...

  4. VIEW SERVER STATE permission was denied on object 'server', database 'master'

    今天一同事反馈使用SQL Server 2012 Management Studio连接SQL Server 2014后,选择数据库中某个表,然后单击右键时,就会遇到下面错误: 这个错误初看以为是权限 ...

  5. MySQL初始化的正确姿势

    1. 背景 mysql安装教程很多,但是有不少讲得过于简单,没有考虑到安全问题.比如说,一些教程里,只设置一个root用户,并且对外网公开,一来容易被破解密码(用户名固定,破解难度自然降了一大截,而且 ...

  6. sizeof

    一.sizeof使用的场合: 1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信.例如: void* malloc(size_t size); size_t fread(v ...

  7. Linux简介及常用命令使用3--vi编辑器

    1.进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 [新建文件]vi +n filename :打开文件,并将光标置于第n行首 [比如:某个shell报错的行数时使用] ...

  8. 利用httpd对tomcat进行负载均衡配置

    实验系统:CentOS 6.6_x86_64 实验前提:提前准备好编译环境,防火墙和selinux都关闭 实验说明:本实验共有2台主机,IP分配如拓扑 实验软件:jdk-8u60-linux-x64 ...

  9. Asp.Net Core 简单的使用加密的Cookie保存用户状态

    在以前的Asp.Net中可以用 FormsAuthentication 类的一系列方法来使用加密的Cookie存储用户身份,使用简单,可控性强.在Asp.Net Core中是否也可以的?答案是当然的. ...

  10. Merge k Sorted Lists

    1. Merge Two Sorted Lists 我们先来看这个 问题: Merge two sorted linked lists and return it as a new list. The ...