面向对象编程
Object Oriented Programming,OOP,是一种程序设计思想,OOP把对象最为程序的基本单元,一个对象包含了数据和操作数据的函数
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行,为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象,自定义的对象数据类型就是面向对象中的类(class)的概念。
举例说明:
假设我们要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个dict表示:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 student1={'name:'ykyk','score':98} 2 student2={'name':'tina','score':81}
处理学生的成绩可以通过函数实现,比如打印学生的成绩:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 def print_score(student): 2 print('%s:%s' %(student['name'],student['score']))
如果采用面向对象的程序设计思想,首先思考的不是程序的执行流程,而是student这种数据类型应该被视为一个对象,这个对象拥有name和score这两个属性,如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,然后,给对象发一个print_score的消息,让对象自己把自己的数据打印出来。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 class student(object): 2 def __init__(self,name,score): 3 self.name = name 4 self.name = score 5 def print_score(self): 6 print('%s: %s' % (self.name, self.score))
给对象发消息实际上就是调用对象对应的关联函数,称之为对象的方法(Method),面向对象的程序写出来类似于这样:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 ykyk = student('ykyk',91) 2 tina = student('tina',89) 3 4 ykyk.print_score() 5 tina.print_score()
面向对象的设计思想是从自然界中来的,因为咋自然界中,类(class)和实例(instance)的概念是很自然的,Class是一种抽象的概念,比如我们定义的Class——student,是指学生这个概念,而实例(instance)则是一个个具体的student,比如,ykyk,tina,是两个具体的student。
面向对象的设计思想是抽象出class,根据class创建instance
面向对象的抽象程度又比函数要高,因为一个class既包含数据,有包含操作数据的方法。
面向对象的特点:
1.数据封装
2.继承
3.多态
一、类和实例
首先定义一个类(class):
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 class student(): 2 def __init__(self,name,age,score): 3 self.name = name 4 self.age = age 5 self.score = score 6 7 8 def print_score(self): 9 print('%s %s:%s' %(self.name,self.age,self.score)) 10 11 12 13 14 15 ykyk = student('ykyk',19,90) 16 17 print(student) 18 print(ykyk) 19 ykyk.print_score()
输出结果:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <class '__main__.student'> 2 <__main__.student object at 0x0000000002342390> 3 ykyk 19:90
可以看到,ykyk指向的就是一个student的实例,0x0000000002342390>是它的内存地址,每一个object的地址都不一样,student本身则是一个类
类的作用就相当于一个模板,实例以这个模板来进行
可以自由的给实例修改属性
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 ykyk.name = 'superman' 2 3 print(ykyk.name)
输出
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 superman
注意:__init__方法的第一个参数永远是self,表示创建实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self。
和普通函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且在调用时,不用传递该参数。
数据封装
把客观事务封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏
继承
继承是指一种能力,它可以使用现有的类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展
通过继承创建的新类称为“子类”或者“派生类”
被继承的类称为基类、父类或者超类
继承的过程,就是从一般到特殊的过程
要实现继承,可以通过“继承(inheritance)”和“组合(composition”来实现
在某些OOP语言中,一个子类可以继承多个基类,但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现
实现方式:
1.实现继承:
实现继承是指使用基类的属性和方法二无需额外编码的能力
2.接口继承
接口继承是指仅使用属性和方法的名称、但是自子类必须提供实现的能力(子类重构父类方法)
在考虑使用继承时,有一点需要注意,那就是两个子类之间的关系应该是属于关系。
抽象类仅定义将由子类创建的一般属性和方法
继承示例
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 author = 'ykyk' 2 3 4 class Heros(object): 5 6 level = 1 7 kills = 0 8 def __init__(self,name,equipment,skill,gift): 9 self.name = name 10 self.equipment = equipment 11 self.skill = skill 12 self.gift = gift 13 14 def hero_info(self): 15 msg = '%s has join the battle ' %self.name 16 print(msg) 17 18 def kill_npcs(self): 19 self.kills += 1 20 msg = '%s killed a npc moster ' %self.name 21 print(msg) 22 23 def kill_hero(self): 24 self.kills += 3 25 msg = '%s kiiled a hero! ' %self.name 26 print(msg) 27 28 def upgrade(self): 29 while self.kills> 6 : 30 self.level +=1 31 self.kills = 0 32 33 class 天灾(Heros): 34 35 def __init__(self,name,equipment,skill,gift,property): 36 super(天灾,self).__init__(name,equipment,skill,gift) 37 self.property = property 38 39 def skills_1(self): 40 msg = '%s is a warrior who can hit other with sword' %self.name 41 print(msg) 42 43 class 近卫(Heros): 44 45 def __init__(self,name,equipment,skill,gift,property): 46 super(近卫,self).__init__(name,equipment,skill,gift) 47 self.property = property 48 49 def skills_2(self): 50 msg = '%s is a wiszard who can kill others by magic '%self.name 51 print(msg) 52 53 54 55 hero1 = 天灾('DP','Eul的神圣法杖','沉默魔法','10级:+4% 技能伤害增强或+6 力量','dark') 56 57 hero2 = 近卫('Axe','刃甲','反击螺旋','10级:+6 力量或+3 魔法恢复速率','dark') 58 59 hero1.hero_info() 60 print(hero1.level) 61 hero1.kill_hero() 62 hero1.kill_hero() 63 hero1.kill_npcs() 64 hero1.kill_npcs() 65 print(hero1.kills) 66 67 hero1.upgrade() 68 print(hero1.level)
面向对象的开发范式大致为:
划分对象——抽象类——将类组织成为层次化结构(继承和合成)——用类与方法进行设计和实现阶段
析构函数
析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。
构造函数
构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。
多态
多态性是允许将赴对象设置成为一个或者更多的他的字对象相等的技术,复制之后,父对象就可以根据当前的赋值给他的子对象的特性以不同的方式运作,简单的说,就是允许将子类类型的指针赋值给父类类型的指针
作用:
接口重用,继承和派生的时候,保证使用“家谱”中任意一类的实例的某一属性时的正确调用
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 author = 'ykyk' 2 3 4 class Heros(object): 5 6 level = 1 7 kills = 0 8 def __init__(self,name,equipment,skill,gift): 9 self.name = name 10 self.equipment = equipment 11 self.skill = skill 12 self.gift = gift 13 14 def hero_info(self): 15 msg = '%s has join the battle ' %self.name 16 print(msg) 17 18 def kill_npcs(self): 19 self.kills += 1 20 msg = '%s killed a npc moster ' %self.name 21 print(msg) 22 23 def kill_hero(self): 24 self.kills += 3 25 msg = '%s kiiled a hero! ' %self.name 26 print(msg) 27 28 def upgrade(self): 29 while self.kills> 6 : 30 self.level +=1 31 self.kills = 0 32 33 class 天灾(Heros): 34 35 def __init__(self,name,equipment,skill,gift,property): 36 super(天灾,self).__init__(name,equipment,skill,gift) 37 self.property = property 38 39 def skills_1(self): 40 msg = '%s is a warrior who can hit other with sword' %self.name 41 print(msg) 42 43 class 近卫(Heros): 44 45 def __init__(self,name,equipment,skill,gift,property): 46 super(近卫,self).__init__(name,equipment,skill,gift) 47 self.property = property 48 49 def skills_1(self): 50 msg = '%s is a wiszard who can kill others by magic '%self.name 51 print(msg) 52 53 def func(obj): 54 obj.skills_1() 55 56 hero1 = 天灾('DP','Eul的神圣法杖','沉默魔法','10级:+4% 技能伤害增强或+6 力量','dark') 57 58 hero2 = 近卫('Axe','刃甲','反击螺旋','10级:+6 力量或+3 魔法恢复速率','dark') 59 60 func(hero1) 61 func(hero2)