编程范式概述:
面向过程 和 面向对象 以及函数式编程
面向过程:(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 = '25'      # 说明:中间人(对象)中可以带有多个值 当作参数传递
zhong_obj1.foo(888)zhong_obj2 = Bar()  # 中间人(对象2) 说明:同一个类 可以被多个对象引用
zhong_obj2.name = 'pitter'
zhong_obj2.age = '20'
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 = nself.age = aself.gender = gdef 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 子类(父类):passson = 子类()
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中查找方法aprint('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

转载于:https://www.cnblogs.com/hellojesson/p/5893732.html

Python 面向对象 基础相关推荐

  1. Python面向对象基础示例_创建对象

    Python面向对象基础示例_创建对象 python是面向对象的语言,你可以很轻松的创建一个类和对象.本书代码源自<<Python 3 Object-Oriented Programmin ...

  2. Python面向对象基础(上)—Python Day7

    导入 --Python面向对象基础 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 面向对象 ...

  3. python面向对象基础_python面向对象基础

    面向对象基础 一.面向对象和面向过程 面向过程: 优点:复杂问题流程化,进而简单化 确定:可扩展性差 面向对象: 优点:可扩展性高 缺点:编写复杂度高于面向过程 二.类与对象 类即类别.种类,是面向对 ...

  4. python面向对象基础-封装

    面向对象就是将编程当成一个事务,对外界来说,事务是直接使用,不用去管他内部的情况.而编程就是设置事务能够做什么事. 类 类是对一系列具有 相同特征和行为的事务的统称,是一个抽象的概念,不是真实存在的事 ...

  5. python面向对象基础语言进阶

    在此感谢前辈们的指导:http://python.jobbole.com/80955/ https://www.cnblogs.com/wupeiqi/p/4766801.html https://w ...

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

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

  7. Python面向对象基础一

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

  8. python面向对象基础-01

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

  9. python面向对象基础知识

    python基础链接 类和对象 类和对象是面向对象编程的两个核心概念. 类 类是对一群具有相同特征或者行为 的事物的一个统称,是抽象的,不能直接使用 特征其实就是一个变量,在类里我们称之为属性. 行为 ...

最新文章

  1. python未将对象引用设置到对象的实例_未将对象引用设置到对象的实例(SystemNullReferenceException)...
  2. Struts 2:處理一個form多個submit
  3. 从原型链看DOM--Node类型
  4. SQLite3的提交事务代码
  5. oracle簇表 数据抽取,Oracle聚簇表
  6. 简书 android底部导航,使用recyclerView封装底部导航栏
  7. MFC开发IM-第十二篇、MFC改变static text背景色为透明
  8. NestedScrollView、ScrollView 加载完自动滑动至底部问题的解决方案
  9. Win2003安装VS.NET2005sp1出现1718错误的解决方案
  10. python:关于三级菜单的新手实现
  11. merge()函数--R语言
  12. gensim中word2vec API参数说明
  13. 从零双排java之Map
  14. 沈阳服务器主板维修,沈阳铁西区附近电脑主板维修
  15. 如何为HTML5 Video载入WebVTT字幕
  16. 算法导论读书笔记(19)
  17. 陈奕迅《歌神HQCD》[WAV分轨]
  18. BootStrap-CSS样式_排版_缩略语
  19. Python授权码生成器(密码生成器)
  20. 树莓派上实现TSL2561对光照强度的获取

热门文章

  1. modules not found(模块未找到)的解决方案
  2. three20 阅读到的代码
  3. SignalR的另类实现技巧
  4. 诺基亚发布首款高功率小基站SCORE以及Flexi Zone LWA支持能力
  5. PYTHON编码处理-str与Unicode的区别
  6. Hibernate配置(2)
  7. 《转载》IOS高级开发~开机启动无限后台运行监听进程
  8. AE 先进的视频画面 快速释放 慢动作
  9. 图像处理之基础---极坐标系及其与直角坐标系的关系
  10. python数据结构之二叉树的实现