爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 17354|回复: 8

[参考资料] Python基础08 面向对象的基本概念

[复制链接]

新浪微博达人勋

发表于 2012-6-2 07:59:01 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 ztftom 于 2012-6-2 15:35 编辑

原文地址,欢迎订阅:
http://www.cnblogs.com/vamei/archive/2012/06/02/2531515.html

        
(面向对象并不难,不要被“面向对象”吓跑)
Python中通过使用类(class)和对象(object)来实现面向对象(object-oriented programming,简称OOP)的编程。
面向对象编程的最主要目的是提高程序的重复使用性,这和函数的目的相类似。
我们这么早切入面向对象编程的原因是,Python的整个概念是基于对象的。了解OOP对于我们深入了解Python很关键。
下面是我对面向对象的理解。

1. 类是属性相近的对象的归类
在人类认知中,会根据属性相近把东西归类,并且给类别命名。比如说,鸟类的共同属性是有羽毛,通过产卵生育后代。任何一只特别的鸟都在鸟类的原型基础上的。
面向对象就是模拟了以上人类认知过程。在Python语言,为了听起来酷,我们把上面说的“东西”称为对象(object)。
先定义鸟类
class Bird(object):
    have_feather
= True
    way_of_reproduction  
= 'egg'
我们定义了一个类别(class),就是鸟(Bird)。在隶属于这个类比的语句块中,我们定义了两个变量,一个是有羽毛(have_feather),一个是生殖方式(way_of_reproduction),这两个变量对应我们刚才说的属性(attribute)。我们暂时先不说明括号以及其中的内容,记为问题1
假设我养了一只小鸡,叫summer。它是个对象,属于鸟类。使用前面定义的类。
summer = Bird()
print
summer.way_of_production
通过第一句来说明summer是类别鸟中的一个对象,summer就有了鸟的所有属性,对属性的引用是通过 对象.属性(object.attribute) 的形式实现的。
(可怜的summer,你就是个有毛产蛋的东西,好不精致)

2. 属性可以是变量,也可以是动作(方法)
在人类日常认知中,我们在通过属性识别类别的时候,有时候会根据这个东西能做什么事情来区分类别。比如说,鸟会移动 (这样就和房屋的类别区分开了)。而这些动作又会带来一定的结果,通过移动会带来位置的变化。
为了酷起见,我们叫这样的一些属性为方法(method)。Python中通过在类的内部定义函数,来说明方法。

class Bird(object):
    have_feather = True
    way_of_reproduction = 'egg'
    def move(self, dx, dy):
        position = [0,0]
        position[0]
= position[0] + dx
        position[
1] = position[1] + dy
        return position

print 'after move:',summer.move(5,8)

我们重新定义了鸟这个类别。
鸟新增一个方法属性,就是移动(函数move)。
它的参数中有一个self,它是为了方便我们引用对象自身。在定义方法的时候,第一个参数必须是self (你也可以起不同的名字,但是一定要有这个参数)。我会在下一讲提到更多关于self的用法。
另外两个参数,dx, dy表示在x、y两个方向移动的距离。move方法会最终改变position的值。
在最后调用move方法的时候,我们只传递了dx和dy两个参数,不需要传递self参数(当然,因为self只是为了内部使用)。
(我的summer现在可以跑一下了)

3. 类别本身还可以进一步细分成子类
比如说,鸟类可以进一步分成鸡,大雁,黄鹂。
在OOP中,我们通过继承(inheritance)来表达上述概念。
[url=]

                               
登录/注册后可看大图
[/url]
class Chicken(Bird):
    way_of_move
= ‘walk’
    possible_in_KFC
= True

class Oriole(Bird):
    way_of_move
= 'fly'
    possible_in_KFC = False

summer
= Chicken()
print summer.have_feather
print
summer.move(5,8)

我们新定义的鸡(Chicken)类的,新增加了两个属性,移动方式(way_of_move)和可能在KFC找到(possible_in_KFC)
在类定义时,括号里改为了Bird,用来说明,Chicken是属于鸟类(Bird)的一个子类(酷点的说法,Chicken继承自Bird),而自然而然,Bird就是Chicken的父类。通过这个说明,Python就知道,Chicken具有Bird的所有属性。我们可以看到,尽管我只声明了summer是鸡类,它依然具有鸟类的属性(无论是变量属性have_feather还是方法属性move)
另外定义黄鹂(Oriole)类,同样继承自鸟类。这样,我们在有一个属于黄鹂的对象时,也会自动拥有鸟类的属性。
通过继承制度,我们可以避免程序中的重复信息和重复语句。如果我们分别定义两个类,而不继承自鸟类,那么我们就必须把鸟类的属性分别敲到鸡类和黄鹂类的定义中,累啊。
(回到问题1, 括号中的object,当括号中为object时,说明这个类没有父类(到头了))
所以说,面向对象提高了程序的可重复使用性
我们可以看到,面向对象实际上基于人类认知时的习惯,将各种各样的东西分类,从而了解世界。我们从祖先开始可能已经练习了这个认知过程有几百万年,所以面向对象是很符合人类思维习惯的编程方法。所谓面向过程(也就是执行完一个语句再执行下一个)实际上是机器思维。通过面向对象的编程,我们实际上是更贴近我们自然的思维方式,也更方便和其他人交流我们程序里所包含的想法,甚至于那个人并不是程序员。

总结:
将东西根据属性归类 ( 将object归为class )
方法是一种属性,表示动作
用继承来说明父类-子类关系。子类自动具有父类的所有属性。
每个对象可以有自己的属性,用self.attribute调用。
定义类:

class class_name(parent_class):
    a
= ...
    b
= ...
   
def method1():
        ...
   
def method2():
        ...

引用属性: object.attribute

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-6-2 09:08:37 | 显示全部楼层
这个写的很好哇,把面向对象跟面向过程通过举例子分开,很容易理解

再好好理解一下,接着做作业了
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-6-2 10:04:07 | 显示全部楼层
tom老师  交作业了

遇到一个小问题  先上代码

  1. class qixiangjiayuan(object):
  2.     atmophere='happy'
  3.     leader='mofangbao'
  4.     handsome_boy='ztftom'
  5.     brithday=[0]
  6.     def age(luntan,day):
  7.         luntan.brithday[0]=luntan.brithday[0]+day
  8. topmad=qixiangjiayuan()
  9. print topmad.atmophere
  10. print topmad.leader
  11. topmad.age(520)
  12. print topmad.brithday
  13. class Grads(qixiangjiayuan):
  14.     work_city='GuangZhou'
  15.     have_girlfriend=True
  16.     have_ipad=True
  17. class FORTRAN(qixiangjiayuan):
  18.     work_city='Beijing'
  19.     have_girlfriend=True
  20.     have_ipad=False
  21. print '-*-*-*-*-*-*分割线-*-*-*-*-*-'
  22. benben=Grads()
  23. print benben.atmophere
  24. print benben.have_girlfriend
  25. yanshenshen=FORTRAN()
  26. print yanshenshen.leader
  27. print yanshenshen.have_ipad
  28. yanshenshen.age(250)
  29. print yanshenshen.brithday




QQ截图20120602100301.jpg

最后那个 我执行了 yanshenshen.age(250)
我想叫程序执行出来250  为何会跟前面的520计算结果相叠加呢? 传递过程中的问题还是?

密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2012-6-2 14:48:46 | 显示全部楼层
topmad 发表于 2012-6-2 10:04
tom老师  交作业了

遇到一个小问题  先上代码

不好意思,我犯错了。我为了把__init__()放在后面讲,用了一个错误的机制。我们这次讲的这些属性都是类的属性,是同一个类之下的所有对象所共有的。而按照之前的意思,position应该是对象的属性(每个东西都有各自的position,position并不相同。),也就是属于summer的自己属性,应该是通过self.position来定义的。
对象的属性的初始化一般在__init__()函数里实现,我想把特殊函数专门弄一讲来说,结果就写错。对原文进行了些改动。
谢谢你的提醒哈,很重要,很重要。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-6-2 16:13:06 | 显示全部楼层
ztftom 发表于 2012-6-2 14:48
不好意思,我犯错了。我为了把__init__()放在后面讲,用了一个错误的机制。我们这次讲的这些属性都是类的 ...

经过更改,程序如下,请tom审阅
  1. class qixiangjiayuan(object):
  2.     atmophere='happy'
  3.     leader='mofangbao'
  4.     handsome_boy='ztftom'   
  5.     def age(luntan,day):
  6.         luntan.brithday=[0,0]
  7.         luntan.brithday[0]=luntan.brithday[0]+day
  8.         return  luntan.brithday[0]

  9. topmad=qixiangjiayuan()
  10. print topmad.atmophere
  11. print topmad.leader
  12. #topmad.age(520)
  13. print topmad.age(520)

  14. class Grads(qixiangjiayuan):
  15.     work_city='GuangZhou'
  16.     have_girlfriend=True
  17.     have_ipad=True

  18. class FORTRAN(qixiangjiayuan):
  19.     work_city='Beijing'
  20.     have_girlfriend=True
  21.     have_ipad=False

  22. print '-*-*-*-*-*-*分割线-*-*-*-*-*-'
  23. benben=Grads()
  24. print benben.atmophere
  25. print benben.have_girlfriend
  26. yanshenshen=FORTRAN()
  27. print yanshenshen.leader
  28. print yanshenshen.have_ipad
  29. #yanshenshen.age(250)
  30. print yanshenshen.age(250)



感觉还是有一点别扭
原来的代码不行了,代码的最后两行,就是改动的部分,纠结了一下,嘿嘿
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2012-6-2 17:01:42 | 显示全部楼层
本帖最后由 ztftom 于 2012-6-2 17:02 编辑
topmad 发表于 2012-6-2 16:13
经过更改,程序如下,请tom审阅

你在定义方法的时候,最好第一个参数叫做self。虽然叫其它名字也是允许的,但一般人都会用self这个名字。读起来会比较容易读。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2012-6-2 17:02:52 | 显示全部楼层
topmad 发表于 2012-6-2 16:13
经过更改,程序如下,请tom审阅

我马上上传下一讲,让你不那么别扭。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2012-6-2 17:09:15 | 显示全部楼层
ztftom 发表于 2012-6-2 17:01
你在定义方法的时候,最好第一个参数叫做self。虽然叫其它名字也是允许的,但一般人都会用self这个名字。 ...

恩,好,说实话,第一次写面向对象的东西,有一点点不很适应,呵呵
tom多多指教
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2012-6-2 17:11:15 | 显示全部楼层
topmad 发表于 2012-6-2 17:09
恩,好,说实话,第一次写面向对象的东西,有一点点不很适应,呵呵
tom多多指教

你可以看09的内容了。结合这两课,应该够日常写面向对象的东西了。
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表