走入计算机的第二十八天(面向对象的程序设计)

一  什么是面向对象的程序设计及为什么要有它

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

优点是:极大的降低了程序的复杂度

缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。

面向对象的程序设计的

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

二类和对象

1 对象也就是一种封装的思想,不过这种思想要先进一步,对象的来源是模拟真是世界,把数据和代码封装在了一起。

2 定义了对象的特征(属性)和行为(方法),但还不是一个完整的对象,将定义的这些称为类(class)。需要类来创建一个真正的对象,这个对象就叫做这个类的以恶实例(instance),也叫实例对象(instance objects)

3python中一切皆为对象,且python3统一了类与类型的概念,类型就是类,所以,不管你信不信,你已经使用了很长时间的类了

1 >>> dict #类型dict就是类dict
2 <class ‘dict‘>
3 >>> d=dict(name=‘egon‘) #实例化
4 >>> d.pop(‘name‘) #向d发一条消息,执行d的方法pop
5 ‘egon‘

  基于面向对象设计一个款游戏:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能,特征即数据属性,技能即方法属性,特征与技能的结合体就一个对象。

  从一组对象中提取相似的部分就是类所有对象都具有的特征和技能的结合体

  在python中,用变量表示特征,用函数表示技能,因而类是变量与函数的结合体,对象是变量与方法(指向类的函数)的结合体

  

  补充几个有意思的点:

  garen_hero.Q()称为向garen_hero这个对象发送了一条消息,让他去执行Q这个函数,完成一个功能,类似的有:

  garen_hero.W()

  garen_hero.E()

  garen_hero.R()

  一个英雄可以攻击另外一个英雄,这就是对象之间的交互

  garen_hero.attack(Riven)

4 类相关知识

初识类

在python中声明函数与声明类很相似

声明函数

1 def functionName(args):
2      ‘函数文档字符串‘
3       函数体 

声明类

 1 ‘‘‘
 2 class 类名:
 3     ‘类的文档字符串‘
 4     类体
 5 ‘‘‘
 6
 7 #我们创建一个类
 8 class Data:
 9     pass 

经典类与新式类

在本节开头介绍得出结论,类是数据与函数的结合,二者称为类的属性

class Garen:        #定义英雄盖伦的类,不同的玩家可以用它实例出自己英雄;
    camp=‘Demacia‘  #所有玩家的英雄(盖伦)的阵营都是Demacia;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。

 类有两种作用:属性引用和实例化

 属性引用(类名.属性)

>>> Garen.camp #引用类的数据属性,该属性与所有对象/实例共享
‘Demacia‘
>>> Garen.attack #引用类的函数属性,该属性也共享
<function Garen.attack at 0x101356510>
>>> Garen.name=‘Garen‘ #增加属性
>>> del Garen.name #删除属性

 实例化(__init__与self)

类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

class Garen:        #定义英雄盖伦的类,不同的玩家可以用它实例出自己英雄;
    camp=‘Demacia‘  #所有玩家的英雄(盖伦)的阵营都是Demacia;
    def __init__(self,nickname,aggressivity=58,life_value=455): #英雄的初始攻击力58...;
        self.nickname=nickname  #为自己的盖伦起个别名;
        self.aggressivity=aggressivity #英雄都有自己的攻击力;
        self.life_value=life_value #英雄都有自己的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。

实例化:类名+括号

>>> g1=Garen(‘草丛伦‘) #就是在执行Garen.__init__(g1,‘草丛伦‘),然后执行__init__内的代码g1.nickname=‘草丛伦’等

self的作用是在实例化时自动将对象/实例本身传给__init__的第一个参数,self可以是任意名字,但是瞎几把写别人就看不懂了。

这种自动传递的机制还体现在g1.attack的调用上,后续会介绍。

一:我们定义的类的属性到底存到哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值

二:特殊的类属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)

5 对象相关知识

对象是关于类而实际存在的一个例子,即实例

>>> g1=Garen(‘草丛伦‘) #类实例化得到g1这个实例,基于该实例我们讲解实例相关知识
>>> type(g1) #查看g1的类型就是类Garen
<class ‘__main__.Garen‘>
>>> isinstance(g1,Garen) #g1就是Garen的实例
True

对象/实例只有一种作用:属性引用

#对象/实例本身其实只有数据属性
>>> g1.nickname
‘草丛伦‘
>>> g1.aggressivity
58
>>> g1.life_value
455
‘‘‘
查看实例属性
同样是dir和内置__dict__两种方式
特殊实例属性
__class__
__dict__
....
‘‘‘

对象/实例本身只有数据属性,但是python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法,绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址都不会一样

>>> g1.attack #对象的绑定方法
<bound method Garen.attack of <__main__.Garen object at 0x101348dd8>>

>>> Garen.attack #对象的绑定方法attack本质就是调用类的函数attack的功能,二者是一种绑定关系
<function Garen.attack at 0x101356620>

对象的绑定方法的特别之处在于:obj.func()会把obj传给func的第一个参数。

6 对象之间的交互

对象是关于类而实际存在的一个例子,即实例

>>> g1=Garen(‘草丛伦‘) #类实例化得到g1这个实例,基于该实例我们讲解实例相关知识
>>> type(g1) #查看g1的类型就是类Garen
<class ‘__main__.Garen‘>
>>> isinstance(g1,Garen) #g1就是Garen的实例
True

 对象/实例只有一种作用:属性引用

#对象/实例本身其实只有数据属性
>>> g1.nickname
‘草丛伦‘
>>> g1.aggressivity
58
>>> g1.life_value
455
‘‘‘
查看实例属性
同样是dir和内置__dict__两种方式
特殊实例属性
__class__
__dict__
....
‘‘‘

对象/实例本身只有数据属性,但是python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法,绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址都不会一样

>>> g1.attack #对象的绑定方法
<bound method Garen.attack of <__main__.Garen object at 0x101348dd8>>

>>> Garen.attack #对象的绑定方法attack本质就是调用类的函数attack的功能,二者是一种绑定关系
<function Garen.attack at 0x101356620>

对象的绑定方法的特别之处在于:obj.func()会把obj传给func的第一个参数。

7 类名称空间与对象/实例名称空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:数据属性和函数属性

其中类的数据属性是共享给所有对象的

>>> id(r1.camp) #本质就是在引用类的camp属性,二者id一样
4315241024
>>> id(Riven.camp)
4315241024

而类的函数属性是绑定到所有对象的:

>>> id(r1.attack)
4302501512
>>> id(Riven.attack)
4315244200

‘‘‘
r1.attack就是在执行Riven.attack的功能,python的class机制会将Riven的函数属性attack绑定给r1,r1相当于拿到了一个指针,指向Riven类的attack功能

除此之外r1.attack()会将r1传给attack的第一个参数
‘‘‘

创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常

时间: 06-27

走入计算机的第二十八天(面向对象的程序设计)的相关文章

走入计算机的第二十九天(继承与派生)

一 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 单继承:就相当于子类继承了一个父类.    多继承:就相当于子类继承了多个父类. python中类的继承分为:单继承和多继承 1 class ParentClass1: #定义父类 2 pass 3 4 class ParentClass2: #定义父类 5 pass 6 7 class SubClass1(ParentClass1): #单继承,基类是P

走入计算机的第十八天(函数的参数)

一  形参和实参 1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元.因此,形参只在函数内部有效.函数调用结束返回主调用函数后则不能再使用该形参变量 2.实参可以是常量.变量.表达式.函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参.因此应预先用赋值,输入等办法使参数获得确定值 二   位置参数: 1 按照从左到右的顺序依次定义的参数,必须被传值,多一个不行,少一个也不行  ,与形参一 一对应叫做位置参数    2关键字

走入计算机的第二十五天(内置模块3之正则表达式)

一 什么是正则表达式 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行. 正则表达式的功能:字符串的模糊匹配查询. 二  re模块 不同的语言均有使用正则表达式的方法,python中是用re模块实现的. 使用的方法格式:变量名=re.re中的其中一个子模块("规则","内容") 元字符 1   .(点) :

走入计算机的第二十七天(模块与包的调用)

一 模块(module)的概念 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件就称之为一个模块(Module). 使用模块的好处:最大的好处是大大提高了代码的可维护性. 其次,编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序的时候,也经常引用其他模块,包

走入计算机的第二十六天(内置模块4)

一 补充正则表达式的其他一些使用方法 1.贪婪模式:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配 1 #贪娈匹配 2 # ret=re.findall("abc+","abccccccccccccccgds") 3 # print(ret) 4 5 # ret=re.findall("abc{1,}","abccccccccccccccgds") 6 # print(ret) 2非贪婪匹配:在满足匹配时,匹配尽

第十篇 面向对象的程序设计

第十篇 面向对象的程序设计 阅读目录 一 面向对象的程序设计的由来 二 什么是面向对象的程序设计及为什么要有它 三 类和对象 3.1 什么是对象,什么是类 3.2 类相关知识 3.3 对象相关知识 3.4 对象之间的交互 3.5 类名称空间与对象/实例名称空间 3.6 小结 四 继承与派生 4.1 什么是继承 4.2 继承与抽象(先抽象再继承) 4.3 继承与重用性 4.4 组合与重用性 4.5 接口与归一化设计 4.6 抽象类 4.7 继承实现的原理(继承顺序) 4.8 子类中调用父类方法 五

第二十八天 月出惊山鸟 —Spring的AOP

6月13日,阴转细雨."人闲桂花落,夜静春山空.月出惊山鸟,时鸣春涧中." 不管在面向过程还是在面向对象里,神奇的"纯"字,似乎永远都充满了无限的可能性.除了函数之所调用.类之所封装,在程序员文化里,对于"纯粹"的感知和定义,既起自于代码,又超越了代码.也就是说,能够真真切切地感觉到纯净的,不仅是我们的每一个Bean和每一个Class,还包括每个Coder的心. 然而,客户的需求是千变万化和千奇百怪的,Spring在为Coder在应对和处理各自不

面向对象的程序设计:Object-oriented programming

在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象. 在现实世界里我们所面对的事情都是对象,如计算机.电视机.自行车等. 对象的主要三个特性: 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为. 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型. 对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同. 比如 Animal(动物) 是一

python之面向对象的程序设计

第一:程序设计思想与发展历程(了解) 1940年以前:面向机器编程最早的是采用机器语言编程,也就是直接使用二进制码来表示机器能够识别的指令和数据.优点:机器语言由机器直接执行,速度快缺点:写起来非常困难,并且不容易修改 汇编语言:用助记符号代替机器指令的操作码,用地址符号或者标号代替指令或操作数的地址优点:比机器语言的二进制码编写方便些缺点:汇编语言本质上还是一种面向机器的语言,编写困难,易出错 脱离机器后:面向过程编程面向过程的结构化程序设计强调功能的抽象和程序的模块化, 它将解决问题的过程看