python面向对象
 
面向对象编程(Object-Oriented Programming )介绍
 
对于编程语言的初学者来讲,OOP不是一个很容易理解的编程方式,虽然大家都知道OOP的三大特性是继承、封装、多态,并且大家也 都知道了如何定义类、方法等面向对象的常用语法,但是一到真正写程序的时候,还是很多人喜欢用函数式编程来写代码,特别是初学者,很容易陷入一个窘境就是 “我知道面向对象,我也会写类,但我依然没发现在使用了面向对象后,对我们的程序开发效率或其它方面带来什么好处,因为我使用函数编程就可以减少重复代码 并做到程序可扩展了,为啥子还用面向对象?”。 对于此,我个人觉得原因应该还是因为你没有充分了解到面向对象能带来的好处。
 
无论用什么形式来编程,我们都要明确记住以下原则:
  1. 写重复代码是非常不好的低级行为
  2. 你写的代码需要经常变更
 
开发正规的程序跟那种写个运行一次就扔了的小脚本一个很大不同就是,你的代码总是需要不断的更改,不是修改bug就是添加新功能等,所以为了日后方便程序的修改及扩展,你写的代码一定要遵循易读、易改的原则(专业术语叫可读性好、易扩展)。
 
如果你把一段同样的代码复制、粘贴到了程序的多个地方以实现在程序的各个地方调用 这个功能,那日后你再对这个功能进行修改时,就需要把程序里多个地方都改一遍,这种写程序的方式是有问题的,因为如果你不小心漏掉了一个地方没改,那可能 会导致整个程序的运行都 出问题。 因此我们知道 在开发中一定要努力避免写重复的代码,否则就相当于给自己再挖坑。
 
还好,函数的出现就能帮我们轻松的解决重复代码的问题,对于需要重复调用的功能,只需要把它写成一个函数,然后在程序的各个地方直接调用这个函数名就好了,并且当需要修改这个功能时,只需改函数代码,然后整个程序就都更新了。
 
面向对象同面向过程相比可以使程序更加容易扩展和易更改。比如 古时候,人们打仗杀人都用刀,后来出来了枪,它的主要功能跟刀一样,也是杀人,然后有人就问,既然刀能杀人了,那还要枪干毛线,哈哈,显而易见,因为枪能更好更快更容易的杀人。
 
关于面向过程和面向对象区别参考
http://www.cnblogs.com/luotianshuai/p/5007044.html

 
定义一个简单的CS游戏
#定义一个字典, 所有的角色的变量名都是一样的,但调用的时候又能区分开分别是谁。
roles = {
:{'name':'Alex',
'role':'terrorist',
'weapon':'AK47',
'life_value': ,
'money': ,
},
:{'name':'Jack',
'role':'police',
'weapon':'B22',
'life_value': ,
'money': ,
},
:{'name':'Rain',
'role':'terrorist',
'weapon':'C33',
'life_value': ,
'money': ,
},
:{'name':'Eirc',
'role':'police',
'weapon':'B51',
'life_value': ,
'money': ,
},
} #print(roles[])#Alex
#print(roles[]) #Jack def shot(by_who):
#开了枪后要减子弹数
pass
def got_shot(who):
#中枪后要减血
who[‘life_value’] -=
pass
def buy_gun(who,gun_name):
#检查钱够不够,买了枪后要扣钱
pass
继续按照这个思路设计,再完善一下代码,游戏的简单版就出来了,但是在往下走之前,我们来看看上面的这种代码写法有没有问题,至少从上面的代码设计中,我看到以下几点缺陷:

.无法确保新添加角色时,他们的属性定义是否正确。
比如 weapon 拼写错误程序无法检测; .角色间无法区分不同的功能
警察和匪徒有不同的功能用函数式编写大家都可以调用,无法区分; .添加新的属性都要添加一遍
假设要新添加防弹衣功能,需要在字典中每个角色都要添加; .每个功能使用相同属性都要重新传入一遍
buy_gun,got_shot每次调用都要传入name; .我们在上面定义了got_shot()后要减血,也就是说减血这个动作是应该通过被击中这个事件来引起的,
但其实我不通过got_shot(),直接调用角色roles[role_id][‘life_value’] 减血也可以.

使用面向对象实现:

class Role(object):
def __init__(self,name,role,weapon,life_value=,money=):
self.name = name
self.role = role
self.weapon = weapon
self.life_value = life_value
self.money = money def shot(self):
print("shooting...") def got_shot(self):
print("ah...,I got shot...") def buy_gun(self,gun_name):
print("just bought %s" %gun_name) r1 = Role('Alex','police','AK47’) #生成一个角色
r2 = Role('Jack','terrorist','B22’) #生成一个角色
先不考虑语法细节,相比函数式写法,上面用面向对象中的类来写最直接的改进有以下2点:
  1. 代码量少了近一半
  2. 角色和它所具有的功能可以一目了然看出来

 面向对象三大特性

封装:
     封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
继承:
     从一般到特殊的过程;它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
多态:
     意味着可以对不同类的对象使用同样的操作。
 
封装

构造方法:
类在实例化 (把一个抽象的类变成一个具体的对象的过程叫做实例化 )对象的时候,会执行初始化方法。

class person(object):
def __init__(self,name,age):
self.name = name
self.age = age obj1 = person('koka',) <=> person.__init__(obj1,'koka',) 解析:
你执行obj1 = person('koka',)时,python的解释器其实干了两件事: .在内存中开辟一块空间指向obj1这个变量名 .调用person这个类并执行其中的__init__(…)方法,相当于person.__init__(obj1,'koka',),这么做是为什么呢?
是为了把'koka',24这2个值跟刚开辟的obj1关联起来,因为关联起来后,你就可以直接obj1.name, obj1.age 这样来调用啦。
所以,为实现这种关联,在调用__init__方法时,就必须把obj1这个变量也传进去,否则__init__不知道要把那2个参数跟谁关联呀。
所以这个__init__(…)方法里的,self.name = name , self.role = role 等等的意思就是要把这几个值存到obj1的内存空间里。
更多内容参考:http://www.cnblogs.com/wupeiqi/p/4493506.html
继承

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

例如:

  猫可以:喵喵叫、吃、喝、拉、撒

  狗可以:汪汪叫、吃、喝、拉、撒

如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实现他们所有的功能,如下所示:

class 猫:

    def 喵喵叫(self):
print '喵喵叫' def 吃(self):
# do something def 喝(self):
# do something def 拉(self):
# do something def 撒(self):
# do something class 狗: def 汪汪叫(self):
print '喵喵叫' def 吃(self):
# do something def 喝(self):
# do something def 拉(self):
# do something def 撒(self):
# do something 伪代码

伪代码

上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:

  动物:吃、喝、拉、撒

     猫:喵喵叫(猫继承动物的功能)

     狗:汪汪叫(狗继承动物的功能)

class 动物:

    def 吃(self):
# do something def 喝(self):
# do something def 拉(self):
# do something def 撒(self):
# do something # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class 猫(动物): def 喵喵叫(self):
print '喵喵叫' # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class 狗(动物): def 汪汪叫(self):
print '喵喵叫' 伪代码

伪代码

class Animal:

    def eat(self):
print "%s 吃 " %self.name def drink(self):
print "%s 喝 " %self.name def shit(self):
print "%s 拉 " %self.name def pee(self):
print "%s 撒 " %self.name class Cat(Animal): def __init__(self, name):
self.name = name
self.breed = '猫' def cry(self):
print '喵喵叫' class Dog(Animal): def __init__(self, name):
self.name = name
self.breed = '狗' def cry(self):
print '汪汪叫' # ######### 执行 ######### c1 = Cat('小白家的小黑猫')
c1.eat() c2 = Cat('小黑的小白猫')
c2.drink() d1 = Dog('胖子家的小瘦狗')
d1.eat()

所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已。

学习了继承的写法之后,我们用代码来是上述阿猫阿狗的功能:

class Animal:

    def eat(self):
print "%s 吃 " %self.name def drink(self):
print "%s 喝 " %self.name def shit(self):
print "%s 拉 " %self.name def pee(self):
print "%s 撒 " %self.name class Cat(Animal): def __init__(self, name):
self.name = name
self.breed = '猫' def cry(self):
print '喵喵叫' class Dog(Animal): def __init__(self, name):
self.name = name
self.breed = '狗' def cry(self):
print '汪汪叫' # ######### 执行 ######### c1 = Cat('小白家的小黑猫')
c1.eat() c2 = Cat('小黑的小白猫')
c2.drink() d1 = Dog('胖子家的小瘦狗')
d1.eat() 代码实例

继承实例

继承重写

class AddrBookEntry(object):
'address book entry class'
def __init__(self,nm,ph):
self.name = nm
self.ph = ph
print("Created instance for:",self.name)
def UpdatePhone(self,newph):
self.ph = newph
print('Updated phone %s for:'%self.ph ,self.name) class EmplAddrBookEntry(AddrBookEntry):
'Employee Address Book Entry class'
def __init__(self,nm,ph,id,em): #重写init
super(EmplAddrBookEntry,self).__init__(nm,ph) #继承父类的init
#AddrBookEntry.__init__(self,nm,ph)
self.empid = id
self.email = em
def updateEmail(self,newem):
self.email = newem
print('Updated e-mail address %s for:'%self.email,self.name) new = AddrBookEntry("koka",'') #父类生成实例
new.UpdatePhone("") #使用方法更新
newnew = EmplAddrBookEntry("akok","","","wlgc.com") #子类生成实例 继承父类的nm,ph 重写id,em
newnew.updateEmail("12345@qq.com") #子类实例使用自己的方法
newnew.UpdatePhone("") #子类实例继承使用父类方法

多重继承

import time
class A(object):
n = 'A'
def f2(self):
print("f2 from A")
def f1(self):
print("f1 from A")
class B(A):
n = 'B'
def f1(self):
print("f1 from B")
#def f2(self):
# print("f2 from B") class C(A):
n = 'C'
def f1(self):
print("f1 from C")
def f2(self):
print("f2 from C") class D(B,C):
n = 'D'
def __del__(self):
#会在程序结束后执行,释放内存
print("deleting the ...") d = D()
d.f1() #输出 f1 from B
d.f2() #输出 f2 from C # 新式类:D -> B -> C -> A 广度查找(从左至右查找最近的)
# 经典类: D-> B -> A 深度查找,在python3.0以后默认为广度查找

多态

实例:
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal):
def talk(self):
return 'Meow!' class Dog(Animal):
def talk(self):
return 'Woof! Woof!' animals = [Cat('Missy'),
Dog('Lassie')] for animal in animals:
print animal.name + ': ' + animal.talk()
"""
def animal_talk(obj):
print(obj.talk()) d = Dog("sanjiangyuan")
c = Cat("sanjiangshui")
animal_talk(c)
animal_talk(d)
"""

python学习笔记六 初识面向对象上(基础篇)的更多相关文章

  1. Python学习笔记整理总结【语言基础篇】

    一.变量赋值及命名规则① 声明一个变量及赋值 #!/usr/bin/env python # -*- coding:utf-8 -*- # _author_soloLi name1="sol ...

  2. python学习笔记五 模块下(基础篇)

    shevle 模块 扩展pickle模块... 1.潜在的陷进 >>> import shelve>>> s = shelve.open("nb" ...

  3. python学习笔记三 文件操作(基础篇)

    文件操作 打开文件 open(name[,mode[,buffering]])   open函数使用一个文件名作为强制参数,然后返回一个文件对象.[python 3.5 把file()删除掉]   w ...

  4. Python学习-第三天-面向对象编程基础

    Python学习-第三天-面向对象编程基础 类和对象 简单的说,类是对象的蓝图和模板,而对象是类的实例.这个解释虽然有点像用概念在解释概念,但是从这句话我们至少可以看出,类是抽象的概念,而对象是具体的 ...

  5. Python学习笔记六

    Python课堂笔记六 常用模块已经可以在单位实际项目中使用,可以实现运维自动化.无需手工备份文件,数据库,拷贝,压缩. 常用模块 time模块 time.time time.localtime ti ...

  6. python学习笔记——多进程间通信——Linux信号基础

    1 信号的基本描述 Signal信号(其全程为软中断信号)是Linux系统编程中非常重要的概念,信号是异步进程中通信的一种方式. 作用是通知进程发生了异步事件.进程之间可以调用系统来传递信号, 本身内 ...

  7. python学习笔记六 面向对象相关下(基础篇)

    面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以将多函数中公用的变量封装到对象中) 对象,根据模板创建的 ...

  8. python 学习笔记9(面向对象)

    面向过程.函数式.面向对象 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象(Object Oriented Programmin ...

  9. python学习日记(初识面向对象)

    面向过程 VS 面向对象 面向过程 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统 ...

随机推荐

  1. 直关的sql 联级更新语句

    在sql-server中用这种写法最直观:UPDATE a SET a.c = b.c FROM table1 ainner join table2 b on b.a=a.aWHERE a.c is ...

  2. Android bindservice使用

    package com.example.myact10; import com.example.myact10.MyService.MyBinder; import android.support.v ...

  3. Inside TSQL Querying - Chapter 2. Physical Query Processing

    Summary Description The SQL language is spoken by most database experts, and all relational database ...

  4. Java如何对ArrayList里的元素排序

  5. APP的UI测试要点

    1.文字显示是否正确 比如与需求图片对比是否正确,无错别字 2.对齐方式是否正确 3.图片 图片显示的篇幅不要太大. 4.颜色是否正确 颜色与需求规定的是否一致

  6. 【python cookbook】【数据结构与算法】17.从字典中提取子集

    问题:想创建一个字典,其本身是另一个字典的子集 解决方案:利用字典推导式(dictionary comprehension)可轻松解决 # example of extracting a subset ...

  7. Mac下好用的取色器 Sip

    总有很多东西,你只是望一眼就已经神魂颠倒.措施有这样的App做的真的是用心的很,养眼,触发你内心冲动的美感.先留下一个,备忘. 太精致了 操作简单,左上角的有心圆点击就可以在任何地方取色了,取色点会z ...

  8. android 开发中的常见问题

    Android studio 使用极光推送, 显示获取sdk版本失败 在 build.gradle(Module.app) 添加 android {    sourceSets.main {      ...

  9. ImageLoader 图片加裁

    // String picurl = article.cateLogo;// ImageLoader.getInstance().displayImage(picurl, holder.cate_Lo ...

  10. Python学习总结:目录

    Python 3.x总结 Python学习总结[第一篇]:Python简介及入门 Python学习总结[第二篇]:Python数据结构 Python学习总结[第三篇]:Python之函数(自定义函数. ...