Board logo

标题: 用正确的小汽车对象学习和熟悉类的概念 [打印本页]

作者: 我不是鱼    时间: 2006-9-1 23:42     标题: 用正确的小汽车对象学习和熟悉类的概念

--------------------------------------------------------------------------------
  
作者:shuke 来源:PHP蓝皮书  
   


  
很多书讲到类总喜欢拿小汽车来做例子,但是有些例子实在是又臭又烂误人子弟,骗人钱财,毁人前程,弱智低级到瞎编一个什么 set_color()函数来教人。实在是白白糟踏了好东西。今天在phpx.com又看到一个受害者,忍不住花了两个小时写了这个教程。

闲话少说,我们来正经的,我们的小车可不是随便让人图图颜色就完了(只能图颜色的是废车)。我们的这个小车不但能够到处乱跑,而且装备了高级GPS全球定位系统,油表,里程表。由于使用了面向对象的技术,驾驭这样的一部小汽车一点都不难。  

举例子首先要提供一些背景材料。我们有一辆小汽车,可以在一个拥有xy坐标的地图上按照东南西北方向任意的行驶,你可以设定小车行驶的方向和距离,小车会向你汇报它的坐标位置。  

其实学习类应该和我们学习其它事物一样,从学习使用开始,然后再学习他的原理。所以我们先来熟悉一下如何正确驾驶这样的一个小汽车:

[复制到剪切板]
CODE:
<?php 
$startPoint 
= & new Position(3,9); //初始一个出发点坐标x=3,y=9  

$myCar = & new Car(500,$startPoint); //我得到一个新的小车,新车初始燃油 500 升,出发地点$startPoint。  

$myCar->setHeading('s'); //给小车设定方向 s:南方 n:北方 w:西方 e:东方。  

if($myCar->run(100)) //然后让小车跑100公里,如果顺利完成任务显示燃油量。如果半途而废,我们显示警报信息。  
{  
    print(
'<br><b>小车一切正常,目前还有燃油:'.$myCar->getGas().'</b>');//获得燃油数  
}  
else  
{  
    print(
'<br><b>小车出问题了: '.$myCar->getWarning().'</b>');//显示警报信息  
}  

$myPosition=$myCar->getPosition();//获得小车当前的位置  

print('<br>我的小车现在<br> X:'.$myPosition->getX().'Y:'.$myPosition->getY());//显示小车的坐标位置 
?> ;

先给自己制造一个小汽车,并且给他装备上一个定位对象 Position。 然后设定方向, 然后让小车奔跑。 最后检查并输出小车的方位。 复杂么?很难理解吗? 虽然这里我们用到了两个对象(类):Car 和 Position 但是我相信即使是初学者也不会觉得上面的代码很困难。  

我们学会如何开车了以后,再来仔细看一看这个小车对象是怎样工作的。定义一个对象其实很简单只需要 用一个关键字class 和一对{}就可以了,所以我们这样定义这两个对象:
class Car {}
class Position{}
当然,仅仅这样的两个类什么也做不了,我们还需要给他们增加一些功能,先从小汽车开始,我们需要能够给小车设定方向并且让小车奔跑所以我们增加两个方法,也就是2个函数只不过这两个函数包含在小车对象内只有通过小车对象才可以使用。
setHeading()  
run()  
class Car
{
function setHeading($direction)
{

}

function run($km)
{

}
}
特别提示:设计一个良好的类的窍门是从如何使用它下手,也就是说先考虑这个对象应当有哪些方法,而不是先确定它有哪些属性。
为了更好的了解小车的状况我们还需要这些方法:  
getGas() 获得小车当前的燃油数  
getPosition() 获得小车当前的位置  
getWarning() 警报信息  
为了完成这些功能我们的小车还需要自己的油表,警报消息,和定位仪。我们把这些也添加到 Car 类中,同时我们还给这个类增加了一个初始化的函数 这个函数名字和类的名字一样,这样就有了一个大体的框架。

[复制到剪切板]
CODE:
<?php 
class Car  
{  
    
/**  
    * 小车的汽油量  
    *  
    *@var  
    *@access  
    */  
    
var $gas;  

    
/**  
    * 里程记录  
    *  
    *@var  
    *@access  
    */  
    
var $meter;  
 
     
/**  
    * 车的位置(由GPS自动控制)  
    *  
    *@var Object position  
    *@access private  
    */  
    
var $position;  
      
    
/**  
    * 发动机每1公里耗油量,这个车是0.1升  
    *  
    *@var Integer  
    *@access private  
    */  
    
var $engine=0.1;  

    
/**  
    * 警报信息  
    *  
    *@var  
    *@access  
    */  
    
var $warning;  
      
    
/**  
    小车的初始化。新车出场当然要  
    1、加汽油。  
    2、里程表归零。  
    3、清除警报信息。  
    4、设定出发位置。  
    */  
    
function Car($gas,&$position)  
    {  
        
$this->gas$gas//加汽油  
        
$this->meter 0;  
        
$this->warning =''//清除警报信息  
        
$this->position $position//设定出发位置  
    
}  
      
    function 
getWarning() //返回警报信息  
    
{  
        return 
$this->warning;  
    }  
      
    function 
getGas() //返回汽油表指数  
    
{  
        return 
$this->gas;  
    }  

    function &
getPosition()  
    {  
        return 
$this->position//返回当前小车的位置  
    
}  

    function 
setHeading($direction='e')  
    {  
          
    }  

    
/**  
    * 开动小汽车  
    *@access public  
    *@param INT 公里数  
    */  
    
function run($km)  
    {  
          
    }  
      

?> ;


这时候最关键的两个方法 setHeading 和 run 就变得简单了,由于小车装备了 Position 对象 $this->position, 所以关于坐标定位的事情它也不用管了, 交给 Position 对象好了, 他自己只要管理好自己的油表,里程表就可以了。完成以后的 Car 类变成这个样子了:

[复制到剪切板]
CODE:
<?php 
class Car  
{  
    
/**  
    * 小车的汽油量  
    *  
    *@var  
    *@access  
    */  
    
var $gas;  

    
/**  
    * 里程记录  
    *  
    *@var  
    *@access  
    */  
    
var $meter;  

    
/**  
    * 车的位置(由GPS自动控制)  
    *  
    *@var Object position  
    *@access private  
    */  
    
var $position;  
      
    
/**  
    * 发动机每1公里耗油量,这个车是0.1升  
    *  
    *@var Integer  
    *@access private  
    */  
    
var $engine=0.1;  

    
/**  
    * 警报信息  
    *  
    *@var  
    *@access  
    */  
    
var $warning;  
      
      
    
/**  
    小车的初始化。新车出场当然要  
    1、加满汽油。  
    2、里程表归零。  
    3、清除警报信息。  
    4、设定出发位置。  
    */  
    
function Car($gas,&$position)  
    {  
        
$this->gas$gas//加满汽油  
        
$this->meter 0;  
        
$this->warning =''//清除警报信息  
        
$this->position $position//设定初始位置  
    
}  

    function 
getWarning() //返回警报信息  
    
{  
        return 
$this->warning;  
    }  
      
    function 
getGas() //返回汽油表指数  
    
{  
        return 
$this->gas;  
    }  

    function &
getPosition()  
    {  
        return 
$this->position//返回当前小车的位置  
    
}  

    function 
setHeading($direction='e')  
    {  
        
$this->position->setDirection($direction); //因为使用了Position 对象,小汽车不需要自己来操心XY坐标值了,交给Position 对象吧。  
    
}  

    
/**  
    * 开动小汽车  
    *@access public  
    *@param INT 公里数  
    */  
      
    
function run($km)  
    {  
        
$goodRunFlag true;//是否成功完成任务。  
        
$maxDistance $this->gas/$this->engine//小车能够跑的最大距离。  
          
        
if(($maxDistance)<$km)  
        {  
            
$this->warning '没有汽油了!';//设定警告信息,能跑多远就跑多远吧。  
            
$goodRunFlag false;//但是任务肯定完成不了。  
        
}  
        else  
        {  
            
$maxDistance=$km//没有问题,完成任务以后就可以停下来休息了。  
        
}  
        
$this->position->move($maxDistance);//在坐标上移动由Position对象来完成,小汽车只要负责自己的油耗和公里表就可以了。  
        
$this->gas -= $maxDistance*$this->engine;//消耗汽油  
        
$this->meter += $maxDistance//增加公里表计数  
        
return $goodRunFlag;  
    }  

?> ;


讲到这里我想我的这篇文章也该结束了。别着急,我当然还记得 Position 类还没有完成,但是有了上面小汽车的例子 Position 应该就非常简单了, 如果你理解了这个小汽车的类, 现在就是你一展身手的时候了, 你来完成这个Position 对象吧, 我相信你能够完成它(其实这正是面向对象和封装的美妙之处)。你需要记住先从Position 的方法开始设计比如:


getX()  
getY()  
move()  
setDirection()  
所谓类就是指某一类的事物,它可以是具体的(Car)也可以是抽象的(Position),我们通过封装简化了使用和操作就像我们使用电视,手机一样一点都不复杂。  

一篇好的入门教程应该  

生动真实的例子。  
不但提供了正确的概念,在变量和函数命名,函数封装和调用上也值的学习。  
即便你熟悉了面向对象编程以后也不会认为当初的例子有什么不妥之处。  
如果你读完教程动手的话一定能够深刻体会到教程的美妙之处,大大减少了走弯路的机会。  
好的代码是可以被人像书一样读懂,你认为呢?
作者: MoXie    时间: 2006-9-2 00:51

先回帖慢慢看……
作者: zccrjj    时间: 2006-9-6 22:12


作者: xiangxubing    时间: 2006-11-22 16:12

好贴
作者: hone033    时间: 2007-4-13 10:45     标题: 非常好!

支持,顶!
作者: sxb_135    时间: 2007-4-23 22:49

很好啊
很好啊
作者: blankyao    时间: 2007-8-3 21:30

先顶下,漫漫来看!
作者: goter    时间: 2007-8-21 08:24

写的不错,感觉和java的类一样
作者: goter    时间: 2007-8-21 08:51

不明白

[ 本帖最后由 goter 于 2007-8-21 09:05 编辑 ]
作者: 罗哥.net    时间: 2007-9-25 15:12


作者: sunflower    时间: 2007-9-30 11:21

先回帖再看
作者: dreamhyz    时间: 2007-11-22 13:28

好的帖子,当然要顶罗
作者: turingwang    时间: 2007-12-18 15:46     标题: 回复 #1 我不是鱼 的帖子

写得不错,好的代码确实可以像书一样被人读懂!

提出问题:

1。PHP真的适合面向编程吗?

PHP中的面向对象编成不像java那样灵活,例如:在PHP中只能儿子继承父亲,而在java中可以实现儿子继承父亲,父亲继承爷爷,最终实现儿子继承爷爷;还有PHP的构造函数也不像java的构造函数那样好用,需要手动编写才可以调用父类的构造函数……, 当然对于优秀的PHP程序员来说这也许算不了什么问题,但从PHP的设计语法来看,他真的适合面向编程吗?

2。PHP的强项是什么?
最近自己打算开发一个小型的网站,使用了面向对象的编程理念;结果越搞越复杂(本人技术水平属于新手上路),失去了本来吸引我的php的开发速度,因为我把大量的时间和精力用在了类的构建和调用上了,花费很多的精力考虑如何构造出最最通用的模块,可是每增加一个功能,就会发现自己原先的设计思路需要改动。

面向对象这真的是PHP的强项吗?
作者: 零点    时间: 2008-1-15 21:27

不错的教程!谢谢哦!呵呵……
作者: xhq6880    时间: 2008-3-8 18:03

好样的,加油哈
作者: zjt2est    时间: 2008-3-29 23:26

好好研究下
作者: Sott    时间: 2008-4-5 14:25

恩,写的不错。
作者: maochencw    时间: 2008-4-18 20:12

ding
作者: geminiblue    时间: 2008-5-9 13:24

引用:
原帖由 turingwang 于 2007-12-18 15:46 发表
写得不错,好的代码确实可以像书一样被人读懂!

提出问题:

1。PHP真的适合面向编程吗?

PHP中的面向对象编成不像java那样灵活,例如:在PHP中只能儿子继承父亲,而在java中可以实现儿子继承父亲,父亲 ...
呵呵,一个站点的开发速度快了,相反,维护速度就慢了,php毕竟不像java那样规范话,记得csdn看见一文章,java是货轮,而php只是竹筏
,不过相信php会发展的更好

至于你说的那个继承的问题,用代码说话了:

[复制到剪切板]
CODE:
<?php
    
class a
    
{
        public function 
a_1(){
            echo 
"this is a->a1()\r\n";
        }
    }
    class 
extends a
    
{
        public function 
b_1(){
            echo 
"this is b=>b_1()\r\n";
        }
    }
    class 
extends b
    
{
        public function 
c_1(){
            echo 
"this is c=>c_1()\r\n";
        }
    }
    
$c = new c();
    
$c->c_1();
    
$c->b_1();
    
$c->a_1();
?> ;



作者: dadatt    时间: 2008-5-22 09:55


作者: dadatt    时间: 2008-5-22 10:10

学习了.
作者: zidian05    时间: 2008-7-14 15:03     标题: 捉虫子

class Car {}
class Position{}
老大这个是类吧,还没实例化呢...相信是笔误,改一下别学别人的"车""误人子弟"就麻烦了呵呵
作者: aivera    时间: 2008-11-5 17:32

非常容易理解,我曾经看到过一个渔具店的例子也很好
作者: paplane    时间: 2009-2-25 09:57

好东西!
作者: pandehong    时间: 2009-3-19 16:30

写得好,可惜的我水平还不够。要不就自己写下position.
作者: zhiyue6666    时间: 2009-3-23 10:58

支持~
作者: zjkjxyying    时间: 2009-3-27 21:37

不错,相当的好,很深入,很好理解,只要学过JAVA的应该都可以了解的!
面向对象理解还是不难的
作者: appserv    时间: 2009-3-31 11:49

好好看哦
作者: bingdong700    时间: 2009-6-3 10:21     标题: 好东西

谢谢啦
作者: haizeng    时间: 2009-12-4 11:33

恩 有意思
作者: aoebaba    时间: 2010-6-8 13:51

很精彩啊,也很生动,只是到后面有点看的不是很明白,不过对我这种初学者来说非常有用了,谢谢。
作者: jig68    时间: 2010-8-13 21:01

转载过去学习咯
作者: jsglass    时间: 2011-6-22 12:40

面向对象的精髓.. 呵呵!Cheap Reading glasses
China sunglasses manufacturer
Sunglasses Wholesale
作者: cfzhs    时间: 2011-8-8 14:46

学习一下








www.hjdao.com
作者: puxi1007    时间: 2011-8-10 15:32

看看。。。。










[url=皮鞋批发|http://www.cnxz.cn/pifa/ ]皮鞋批发|http://www.cnxz.cn/pifa/ [/url]
作者: a123101    时间: 2011-8-17 14:44

好贴,支持,呵呵
作者: cc252946877    时间: 2011-10-31 08:25

不错,顶
作者: rerwwer    时间: 2013-1-2 11:13     标题: 乐购时尚网

这款产品我不太了解,我觉得现在在喝的NE美白茶很值得推荐给大家。没有副作用,效果又好,价格也划算,是全身的永久的一个美白效果。喝了3个月后我现在可以完全不用任何化妆品了,皮肤每天都水水的。我在乐购时尚网http://www.letgogo.com/#r-pzxz定的,你可以也去了解下




欢迎光临 PHP爱好者论坛 (http://www.phpfans.net/bbs/) Powered by Discuz! 6.1.0