无忧岛

12 八, 2010

php面向对象OOP编程教程(九) - 类的重载

Posted by: kinglife In: php

在PHP中,函数是不能重名的,同一个类中方法也不能重名,我们这里所说的重载,是指子类方法父类方法同名的方式对父类方法进行覆盖。很多时候,子类可以继承父类的方法直接拿过来用,但是有一些时候,子类需要覆盖父类原有的方法,为自己扩展一些新功能。我们通过代码来分析,同样要注意看注释部分哦:


class Role //角色类
{
    //属性部分
    public $role_name; //名字

    //方法部分
    public function roleTalk() //说话
    {
        echo '我的名字叫:'.$this->role_name.'<br />';
    }
}

class RoleSon extends Role //角色儿子类 继承 角色类
{
    //属性部分
    public $role_nickname; //小名(新的属性)
       
    //方法部分
    public function roleTalk() //说话(重载覆盖)
    {
        echo '我的名字叫:'.$this->role_name.'<br />';
        echo '我的小名叫:'.$this->role_nickname.'<br />';
    }
}

//实例化角色类
$brother_chun = new Role();
$brother_chun->role_name = '春哥'; //名字
$brother_chun->roleTalk(); //父类原有方法

//实例化角色儿子类
$brother_chun_son = new RoleSon();
$brother_chun_son->role_name = '春哥之子'; //名字
$brother_chun_son->role_nickname = '狗胜'; //小名(儿子特有)
$brother_chun_son->roleTalk(); //子类覆盖方法

以上代码将输出:

我的名字叫:春哥
我的名字叫:春哥之子
我的小名叫:狗胜

通过上面的代码我们可以看到,子类里有一个新的属性$role_nickname,这个子类里的属性是无法被父类roleTalk()方法访问的,如果子类通过继承直接使用roleTalk()方法话,那么新的属性就会毫无用处了,因此我们可以通过在子类里建立一个与父类同名的方法来重载,即覆盖父类原有的方法来达到我们的目的——让春哥之子说出自己的小名。

那么有人可能就要问了,我们在子类重新定义一个说话的新方法,比如newRoleTalk()不就得了?效果还不是一样。但是我必须告诉大家,最好不要这么做,因为这不符合现实的逻辑,就好像一个人只有一个嘴巴,我们不可能为了让人多说一句话就多长一个嘴巴,设想如果春哥真长出了N个嘴巴,我们就不用等到2012世界末日了对不对?

那么又有人要问了,roleTalk()原有方法里面只有一行代码,我们要利用重载来扩展一些新功能十分容易搞定,如果roleTalk()里面有成百上千行代码的话,而且父类代码是封装的我们无法查看,那事情不就大条了?的确是这样的,但是不要着急,PHP为我们提供了完美的解决方案来调用父类方法的原有代码,只需要在重载时添加新的代码即可,方法如下:

方法一(建议使用)


parent::方法的名称();

方法二(不建议使用)


父类的名称::方法的名称();

完整代码如下:


class Role //角色类
{
    //属性部分
    public $role_name; //名字

    //方法部分
    public function roleTalk() //说话
    {
        echo '我的名字叫:'.$this->role_name.'<br />';
    }
}

class RoleSon extends Role //角色儿子类 继承 角色类
{
    //属性部分
    public $role_nickname; //小名(新的属性)
       
    //方法部分
    public function roleTalk() //说话(重载)
    {
        parent::roleTalk(); //父类方法原有的代码
        echo '我的小名叫:'.$this->role_nickname.'<br />'; //子类方法新增的代码
    }
}

//实例化角色类
$brother_chun = new Role();
$brother_chun->role_name = '春哥'; //名字
$brother_chun->roleTalk(); //父类原有方法

//实例化角色儿子类
$brother_chun_son = new RoleSon();
$brother_chun_son->role_name = '春哥之子'; //名字
$brother_chun_son->role_nickname = '狗胜'; //小名(儿子特有)
$brother_chun_son->roleTalk(); //子类覆盖方法

以上代码依然将输出:

我的名字叫:春哥
我的名字叫:春哥之子
我的小名叫:狗胜

这样一来,我们就可以轻松的利用重载为原有方法扩展新功能了。OK,那么今天就玩到这里,再次感谢大家的支持,我会抽时间尽力尽快更新的。

作者:hetty 首发地址:http://www.im286.com/thread-4823948-1-1.html

 

新版本就快要完成了,将会有很多新英雄,新道具和平衡性改动,以下是预览#2:

1.队长模式(Captains Mode)(即-cm):6.68的CM模式中将会有一个全新的Ban&Pick系统.
旧系统:4个Ban然后是5个Pick.
新系统:3个Ban3个Pick,完成后再进行2个Ban和2个Pick.
关于具体的Ban&Pick顺序将会在Changelog中详细介绍.

2.一个新道具,毒液之球(Orb of Venom).

3.Tiny将会从A杖加成中获得一个新技能.

4.动力场(Kinetic Field),一个新英雄的新技能之一.

——————————————————
PS:动力场为个人翻译…官方翻译请等待官方内幕组组长的内幕…

Tags: ,

万众期待的DotA 6.68预告片终于放出啦!
新的金钱系统,新的英雄,小小有了蓝杖后的新技能,均在片中一一呈现.我们有理由相信6.68的发布时间指日可待.
从视频中看到的部分画面:

1.拿着大棒子的小小(估计是出了蓝杖了的效果)
2.华丽的仙女龙
3.用直升飞机攻击的英雄
4.一些尚未清楚的新英雄
5.很多华丽的技能效果

慢慢欣赏吧.

视频转载自:YouTube
http://www.youtube.com/watch?v=LNTT5J54V7w&feature=player_embedded

23 七, 2010

[视频]dota 6.67C bug小鸡希瓦war3报错bug

Posted by: kinglife In: Dota

继上文让鸟带有攻击力的bug之后又搜集了两个dota 6.67C的bug.

此视频中有两个bug,操作方法在视频中也有讲解:

一是RD模式 未被选的人物会动起来的bug

此bug对实战毫无影响的,但是挺有意思,那么如何实现的呢,我们接下来讲解:
首先你自己必须已经选完英雄.
先选中RD圈中的模型,就是未被选的英雄,然后同时按下SHIFT+CTRL键,点击你自己的英雄头像,就可以同时选中模型和英雄,这时候你看到队伍栏里有了2个单位.
使用TAB切换,然后用M键移动,然后用M(指令move)点地方就可以了,模型会缓慢移动,英雄也会往那个方向移动.
先选中你想移动的英雄,注意是还没被人选掉的那些…

第二个bug也叫小鸡希瓦bug

此bug也是比较邪恶的bug,浩方和vs均有人测试过.
小鸡BUG 比之前的小鸡臂章 更牛 次BUG 不需要队友的配合 自己独立可完成

当然了 所需的金钱会比小鸡臂章贵 需要小鸡 西瓦 艺人面罩 守护指环 精气球 或者能量球(主要是为了让小鸡有蓝可以使用西瓦而已)

1.合出西瓦
2.给鸡一个守护指环和一个精气球 或者能量球 摁住SHIFT 拿远处的艺人面罩 并按一下C 小鸡身上的圣殿不会合成
3.把西瓦放在小鸡身上,并使用 WAR3 报错,VS对战平台实际bug效果如下图

dota 6.67C 小鸡希瓦bug

dota 6.67C 小鸡希瓦bug


6.67C bug 小鸡希瓦

Tags: , ,

一个来自youtube的视频,DOTA 6.67C的一个小BUG,由Dustbringer发现并制作视频.
DotA 6.67C bug大概触发步骤是:

1. 选择一名英雄
2. 买一个散华放在地上
3. 买一个夜叉放在地上
4. 买一个小鸡卷轴变鸡
5. 买一个小鸟卷轴放在小鸡身上
6. 让小鸡先去拿夜叉->按住shift拿散华->按住shift点F(变鸟)
然后你的小鸟就有了35-41的攻击力,但是它只能攻击飞行单位,因为是魔法攻击,所以对面的鸟和大飞龙这些受免疫单位是不能被攻击的。剩下的只有小飞龙和兽王的鹰。

下面是视频地址,希望你能喜欢


dota 6.67C 最新bug-小鸟带攻击力

Tags: ,

22 七, 2010

php面向对象OOP编程教程(八) - 类的继承

Posted by: kinglife In: php

继承是怎么一个情况呢?和遗传有点相似,但是又不完全相同,比如儿子可以继承父亲的特征,而且还可以拥有自己的特征;同样的子类可以继承父类的属性和方法,而且还可以拥有自己的属性和方法。但是要注意一点,类的世界里面只有”父子关系“,毕竟类不是真实的动物,会有公的和母的之分,还要交配才产下子类,没有这种事情,这只是一个形象的比喻而已。由一个基本的类派生出另一个类,那么这个基本的类就是父类,它所派生出来的类就叫做子类,所以请看下面。

父类也可以叫超类
子类也可以叫派生类

如果你觉得我有性别歧视的嫌疑,当然你也可以叫它们母类和女类,怎么叫无所谓,反正它们是“单性繁殖”,只要理解这点就可以了。想想平时你接触得最多的文件夹,根目录和子目录的关系就和这个道理差不多了……连我自己都觉得啰嗦了,主要是多照顾初学者朋友们,先上图吧,看看更健康。

在PHP和JAVA等大多数语言中,类只允许单继承,也就是说一个子类只能有一个父类;而在C++等一些语言中,类允许多继承,也就是说一个子类可以有多个父类。我个人觉得单继承更符合现实的逻辑,而且我们现在玩的是PHP的OOP,就不对多继承进行过多的讨论了。

php面向对象-类的单继承

php面向对象-类的单继承

也不妨来看看多继承的图,顺便了解下吧:
php面向对象编程-类的多继承

php面向对象编程-类的多继承

 

前面说了,我个人觉得多继承是不符合现实的逻辑的,就是上图所示的样子.但是多继承这个功能是十分有用的,所以PHP为我们引入了接口,接口可以解决多继承的问题,同时又符合了现实的逻辑.关于接口这个东东,我们会在后面的章节中讲解.

现在图看完了,那么打起精神来看代码吧,为了便于演示和便于大家理解,我把所有属性和方法都声明为了public,再次重声,我们不建议这么做:

class Role //角色类
{
//属性部分
public $role_name; //名字

//方法部分
public function roleTalk() //说话
{
echo $this->role_name.':我会说话
';
}

public function roleFight() //发招
{
echo $this->role_name.':我会发招
';
}
}

class RoleSon extends Role //角色儿子类 继承 角色类
{
//方法部分
public function roleEat() //吃饭(儿子类自己的方法)
{
echo $this->role_name.':我会吃饭(儿子特有)
';
}
}

class RoleGrandson extends RoleSon //角色孙子类 继承 角色儿子类
{
//方法部分
public function roleShit() //拉屎(孙子类自己的方法)
{
echo $this->role_name.':我会拉屎(孙子特有)
';
}
}

//实例化角色类
$brother_chun = new Role();
$brother_chun->role_name = '春哥';
$brother_chun->roleTalk();
$brother_chun->roleFight();

//实例化角色儿子类
$brother_chun_son = new RoleSon();
$brother_chun_son->role_name = '春哥之子';
$brother_chun_son->roleTalk();
$brother_chun_son->roleFight();
$brother_chun_son->roleEat();

//实例化角色孙子类
$brother_chun_grandson = new RoleGrandson();
$brother_chun_grandson->role_name = '春哥之孙';
$brother_chun_grandson->roleTalk();
$brother_chun_grandson->roleFight();
$brother_chun_grandson->roleEat();
$brother_chun_grandson->roleShit();

从上面的代码我们已经可以看出继承一个类的步骤非常简单,在子类的名称后面加上extends关键词,再跟上所要继承的父类的名称即可:


class 子类的名称 extends 父类的名称
{
……
}

我们来看看示例代码的输出结果:

春哥:我会说话
春哥:我会发招
春哥之子:我会说话
春哥之子:我会发招
春哥之子:我会吃饭(儿子特有)
春哥之孙:我会说话
春哥之孙:我会发招
春哥之孙:我会吃饭(儿子特有)
春哥之孙:我会拉屎(孙子特有)

我们能发现子类不但可以继承父类的属性和方法,也可以拥有自己的属性和方法.如果我们尝试用”春哥”去访问子类的特有方法,那么程序就会报错.

“春哥之孙”虽然仅仅是继承了”春哥之子”,但是由于”春哥之子”继承了”春哥”,所以”春哥之孙”同时拥有它两个祖宗的属性和方法.

所以说继承这个东东是十分好用啊,你可以利用一个父类来派生出无数个功能更加强大或有特殊用途的子类来.比如把”人类”定义为一个父类,那么通过类的继承,按照性别就可以派生出”男人类”和”女人类”,按照人品就可以派生出”好人类”和”坏人类”,按照职业就可以派生出”工人类”和”农民类”……如此这般,他们同是人类,但又有各自的特点.

以上,什么代码重用易于维护之类老生常谈的好处我就不多说了,大家自己慢慢体会吧,今天就玩到这里.

作者:hetty 首发地址:http://www.im286.com/thread-4823948-1-1.html

15 七, 2010

php面向对象OOP编程教程(七) - 类的特殊方法

Posted by: kinglife In: php

这些特殊方法你也可以叫它们做特殊函数,因为我们前面说过了,方法就是类里面的函数。实际上前面我们已经玩过两个特殊方法了,还记得吗?就是构造方法析构方法,即__construct__destruct这两个方法。那么希望大家记住,PHP类里面凡是以双下划线开头的方法,都有特殊作用,并且都会自动执行

今天我们就来玩另外四个特殊方法,它们分别是:__set()__get()__isset()__unset()

大家注意,之前因为还没有讲到这些特殊方法,同时也是为了方便演示,很多代码中属性都是用默认的public作为声明的,既然现在我们开始玩这些新知识了,那么在此声明,我们不建议将属性声明为默认的public

一般情况下,直接从类的外部访问和设置属性是个很糟糕的想法,因为我们说过了,OOP的优点是封装,而且鼓励使用封装,因此我们在声明属性的时候,应该使用privateprotected,这更符合OOP的编程思想和现实的逻辑。但是,很多情况下我们仍然需要访问和设置属性,而且是经常性的,于是PHP为我们提供了两个方法,用__get()访问属性,用__set()设置属性

我们先通过代码来看看它们是怎么用的,然后再来分析,请结合注释仔细看:

class Role //角色类
{
    //属性部分
    private $role_name; //封装:角色的名字
    private $role_sex; //封装:角色的性别
    private $role_skill; //封装:角色的技能

    //方法部分
    private function __get($attribute_name) //允许访问属性(有一个参数:传入属性的名称)
    {
        if($attribute_name == 'role_name' || $attribute_name == 'role_sex') //如果是:名字、性别
        {
            return $this->$attribute_name; //就允许访问
        }
    }
       
    private function __set($attribute_name,$attribute_value) //允许设置属性(有两个参数:传入属性的名称和值)
    {
        if($attribute_name == 'role_name' || $attribute_name == 'role_sex') //如果是:名字、性别
        {
            $this->$attribute_name = $attribute_value; //就允许设置
        }
    }
}

//将角色类实例化得到一个对象
$brother_chun = new Role();

//设置属性
$brother_chun->role_name = '春哥'; //可以设置:姓名
$brother_chun->role_sex = '男'; //可以设置:性别
$brother_chun->role_skill = '霸气菊花残'; //无法设置:技能

//访问属性
echo $brother_chun->role_name.'<br />'; //可以访问:姓名
echo $brother_chun->role_sex.'<br />'; //可以访问:性别
echo $brother_chun->role_skill.'<br />'; //无法访问:技能

不要看到代码就烦哦,我刚学编程的时候也是这样,这是个坏习惯,因为无论你的理论基础有多么的扎实,如果看不懂代码那也是白搭,更不要说去写了。养成分析代码的好习惯,尤其是去看别人写的优秀的代码,那样会使自己进步非常快。

注意:这里参数是带$号的,关于这个问题貌似“PHP圣经”又写错了几个例子,在此提醒大家,请与属性做好区别。

参数:$this->$something
属性:$this->something

__get()方法用于访问属性,当我们试图访问一个属性的时候,它会自动将属性的名称作为参数传入,并且返回属性的值。
__set()方法用于设置属性,当我们试图设置一个属性的时候,它会自动将属性的名称和值作为参数传入并执行设置操作,没有返回值。

通过运行代码我们会发现,虽然所有属性都被声明为private,即封装私有属性,但是通过__get()方法和__set()方法,我们可以允许某些属性(姓名、性别)能够被访问或设置,并且可以定制一些个性化的条件控制属性的访问和设置,比如我们只允许把性别设置成“男”或“女”,而不能设置为“人妖”等等。如果我们删除这两个特殊方法,试图直接访问或设置属性,那么程序就会报错。

好,那么这两个特殊方法就玩到这里,请大家多看代码和注释,并且尝试修改程序,通过这种方式来进一步了解它们。

下面玩__isset()__unset()这两个特殊方法,我们在原有代码的基础上新增几行代码:

class Role //角色类
{
    //属性部分
    private $role_name; //封装:角色的名字
    private $role_sex; //封装:角色的性别
    private $role_skill; //封装:角色的技能

    //方法部分
    private function __get($attribute_name) //允许访问属性(有一个参数:传入属性的名称)
    {
        if($attribute_name == 'role_name' || $attribute_name == 'role_sex') //如果是:名字、性别
        {
            return $this->$attribute_name; //就允许访问
        }
    }
       
    private function __set($attribute_name,$attribute_value) //允许设置属性(有两个参数:传入属性的名称和值)
    {
        if($attribute_name == 'role_name' || $attribute_name == 'role_sex') //如果是:名字、性别
        {
            $this->$attribute_name = $attribute_value; //就允许设置
        }
    }
    //新增部分
    private function __isset($attribute_name) //检测属性是否设置(有一个参数:传入属性的名称)
    {
        return $this->$attribute_name; //返回结果
    }
       
    private function __unset($attribute_name) //删除属性(有一个参数:传入属性的名称)
    {
        unset($this->$attribute_name); //进行删除
    }
}

//将角色类实例化得到一个对象
$brother_chun = new Role();

//设置属性
$brother_chun->role_name = '春哥'; //可以设置:姓名
$brother_chun->role_sex = '男'; //可以设置:性别
$brother_chun->role_skill = '霸气菊花残'; //无法设置:技能

//访问属性
echo $brother_chun->role_name.'<br />'; //可以访问:姓名
echo $brother_chun->role_sex.'<br />'; //可以访问:性别
echo $brother_chun->role_skill.'<br />'; //无法访问:技能

//新增部分
echo var_dump(isset($brother_chun->role_name)); //检测并输出变量是否被设置
unset($brother_chun->role_name); //删除此属性
echo $brother_chun->role_name.'<br />'; //由于属性被删除,因此没有输出

__isset()__unset()这两个特殊方法的原理和__get()和set()方法的原理是一样的,即将属性作为参数传入,并在类的内部进行处理。说白了,这两个特殊方法就是为了方便在属性被封装的情况下,允许在类的外部使用isset()和unset()这两个PHP函数,更多的也没有什么好说的了,大家看代码和注释吧,尝试着修改运行看看,OK,今天就玩到这里。

作者:hetty 首发地址:http://www.im286.com/thread-4823948-1-1.html

15 七, 2010

php面向对象OOP编程教程(六) - 类的封装

Posted by: kinglife In: php

这里给大家一个小小的友情提示,由于论坛里的代码没有颜色提示,而代码里又含有大量详细的注释,虽然我已经仔细书写代码格式,但是在颜色相同的情况下,可能仍然不便于阅读。因此在代码太长导致大家眼花缭乱的时候,大家可以把代码复制下来,到有颜色提示的编辑器里阅读,比如Zend Studio、Deamweaver、Eclipse等等,这样感觉会好很多。

好,那么我们今天开始玩类的封装,什么是封装呢?额……就是起来(汗), 其实大部分专业术语也很好从字面上的意思去理解,只不过绝大多数人一涉及到技术方面的问题,就习惯性的往高深的方向去想,其实没有必要,我们要尽量以我们自己容易理解的方式去想,这才是玩道,因为它们本就不是什么高深莫测的东西。

封装的作用是不允许别人随意从类的外部使用属性和方法,只留给别人一些有限的属性和方法去使用。OOP是鼓励使用封装的,那么到底封装有什么好处呢?很多书对于封装的好处三言两语就带过了,十分含糊,我在这里会尝试着给大家讲明白。

比如大家熟知的国内品牌机联想电脑,它就属于一种封装,对于不懂硬件的朋友来说,CPU、显卡、主板、硬盘、内存这些乱七八糟的硬件都被机箱封装起来了。机箱里面到底有些什么硬件?这些硬件对于电脑来说有些什么作用?它们到底是如何协同运转的?我们不需要去关心!因为我们只要会开机、会关机、会玩游戏就好了,这样我们的目的就达到了!但同时机箱里又提供了光驱、电源等有限的东西,方便我们可以从外部直接使用它们。

所以你说,一个封装的类,你拿过来,只需要知道怎么使用就可以了,根本不需要去关心它内部是怎么实现功能的,根本不需要去瞅那复杂的代码一眼,这是对于使用者来说的。

那么对于开发者来说呢?很多时候开发者不希望使用者能够随意去碰类内部的东西,因为那样可能会导致一些不可预料的事情发生,就像不懂硬件的朋友把机箱拆开,把里面硬件胡乱的拔来插去,那么电脑可能就无法启动,甚至烧坏,爆炸也说不定,这肯定不是开发者愿意看到的事情。

通常一个完整的系统是由无数个封装类构成的,它们每个都是一个独立的部分,但是又可以相互相通,这对于于团队开发、分工协作是十分有帮助的,比如说你做角色,我做地图,我要用角色的时候就直接就拿过来用,谁有闲功夫管你角色类里面都写了些什么代码,我自己的工作都还忙不过来呢;而且还大大的减少了排错的难度,就像电脑坏了,显卡坏了就修显卡,内存坏了就修内存,不需要把整个机箱里的硬件从头到尾修一遍,那还不如丢掉重新买一台。

所以说,我们要把尽多的工作交给类完成,把尽少的工作交给人完成,这才是正确的OOP主导思想。在类里面,属性和方法通常有公有的和私有的,又是些专业术语,不要紧张,我再次把它们通俗化:

公有就是允许别人用
私有就是不许别人用

在PHP中,类的属性和方法默认公有的,但是我们不建议用默认的方式来定义公有的属性和方法,因为那不利于代码的可读性,我们从小要养成良好的编程习惯,我们要习惯用public访问修饰符来声明某个属性和方法是公有的。

请看下面两例代码,它们实际上是一样的,只不过一个是默认的,另一个是我们通过访问修饰符定义的。

默认方式(不建议使用)

class 类的名称
{
    var $属性的名称; //没有访问修饰符,有var关键字

    function 方法的名称(参数列表) //没有访问修饰符
    {
        ……
    }
}

声明方式(建议使用)

class 类的名称
{
    public $属性的名称; //有访问修饰符,var关键字被去掉了

    public function 方法的名称(参数列表) //有访问修饰符
    {
        ……
    }
}

注意:声明属性的时候,我们先要去掉var关键词,然后再前面加上访问修饰符public;声明方法的时候,直接在前面加上访问修饰符public即可。

我们来认识一下PHP类中的三个访问修饰符:

访问修饰符 声明类型 允许外部使用 允许子类使用
public 公有
protected 私有  
private 私有    

从上表我们可以看到,通过protectedprivate这两个访问修饰符可以将属性和方法声明为私有的,即将它们封装起来,不许别人用。它们的区别仅仅在于对子类的访问控制,关于子类我们会在后面类的继承里面讲到,现在不用去管它,我们现在的首要任务是跟这三个访问修饰符混个熟脸。

好,我们来玩一下代码,看看是不是真的是这么一回事情:

class Role //角色类
{
    //属性部分
    public $role_name; //角色的名字,请尝试将public换成protected或private进行封装

    //方法部分
    public function roleTalk() //角色说话,请尝试将public换成protected或private进行封装
    {
        echo '我会说话';
    }
}

//实例化一个对象
$brother_chun = new Role();

//设置属性
$brother_chun->role_name = '春哥';

//访问方法
$brother_chun->roleTalk();

上面这段代码将属性和方法声明为public时,程序运行正常;若尝试将属性或方法的访问修饰符换成protectedprivate,那么程序就会报错。因为私有的属性和方法是不允许从类的外部使用的。大家可以自己去亲自试验一下,体会一下,这样可以加深理解。那……今天就玩到这里吧。

作者:hetty 首发地址:http://www.im286.com/thread-4823948-1-1.html

所谓构造方法,就是在创建对象时自动执行的方法,也就是说,当你new一个对象的时候,不管你访不访问它,它都会自动执行。它是可以带参数的哦。构造方法通常用来执行一些初始化任务。

构造方法的方法名称必须是 __construct ,注意前面是两个下划线,这是PHP5中的改进,在PHP4中,构造方法和其他语言一样,必须和类的名称相同,当然你要使用这种方式也可以,PHP5还是会认的,但是我不建议这么做,因为那样代码的可读性不强,而且万一某天你想修改类的名称时,你同时还得去修改构造方法的名称,因此我觉得PHP5这个小小的改进比其他语言显得更灵活些。

构造方法(建议使用)

class Role //角色类
{
    function __construct(参数列表); //构造方法
    {
        ……
    }
}

构造方法(不建议使用)

class Role //角色类
{
    function Role(参数列表); //构造方法
    {
        ……
    }
}

OK,我们来玩一下代码看看:

class Role //角色类
{
    //属性部分
    var $role_name; //角色的名字
    var $role_sex; //角色的性别
    var $role_skill; //角色的技能

    //方法部分
    function __construct($name,$sex,$skill) //构造方法,自动执行
    {
       $this->role_name = $name; //将参数传进来,给“姓名”属性一个初始值
       $this->role_sex = $sex; //将参数传进来,给“性别”属性一个初始值
       $this->role_skill = $skill; //将参数传进来,给“技能”属性一个初始值

       echo $this->role_name.'横空出世了<br /><br />'; //如果这句话被输出,说明构造方法自动执行了
    }

    function roleTalk() //角色说话
    {
        echo $this->role_name.'说:'.'我是一个'.$this->role_sex.'人<br />'; //输出:(角色的名字)说:我是一个(角色的性别)人
    }

    function roleFight() //角色发招
    {
        echo $this->role_name.'使出了一招:'.$this->role_skill.'<br /><br />'; //输出:(角色的名字)使出了一招(角色的技能)
    }
}

//实例化一个对象,同时将构造方法所需要的参数传入
$brother_chun = new Role('春哥','男','霸气菊花残');

//属性设置(因为我们我们已经在构造方法中给了属性初始值,所以不需要设置了)

//访问方法
$brother_chun->roleTalk();
$brother_chun->roleFight();

运行后我们可以得到以下结果:

春哥横空出世了

春哥说:我是一个男人
春哥使出了一招:霸气菊花残

我们可以看到第一句话“春哥横空出世了”被输出了,虽然我们并没有访问构造方法,这是因为构造方法在创建对象时就被自动执行了。

虽然我们并没有在类的外部设置属性,但是后两句话依然输出了“春哥”的姓名、性别和技能属性,因为我们在构造方法中给了它们一个初始值,这个初始值就是我们传入的参数。当然,在有已经初始值的情况下,我们依然可以在类的外部重新设置“春哥”的属性。

好了,构造方法我们就完到这里,现在来我们开始玩析构方法,析构方法和构造方法正好相反,也就是在销毁对象时自动执行的方法,它是不带参数的,WHY?因为new一个对象的时候,后面只有一个括号,所以参数只能一个方法,而构造方法相对来说更加有用,所以就传给它咯,而且它可以为析构方法提供所需要的初始值。因此析构也不需要参数。析构方法通常用来执行一些善后工作。

构造方法的方法名称必须是 __destruct,注意前面也是两个下划线,这里要强调一下,PHP中凡是以双下划线开头的东东都有特殊作用。析构方法也是PHP5中的新改进,但是PHP4中没有析构方法,所以请不要尝试在PHP4中使用析构方法,否则电脑爆炸,后果自负,呵呵。

析构方法

class Role //角色类
{
    function __destruct(); //析构方法
    {
        ……
    }
}

那么结合前面的代码,我们把析构方法加进去,也来玩玩析构方法的代码吧:

class Role //角色类
{
    //属性部分
    var $role_name; //角色的名字
    var $role_sex; //角色的性别
    var $role_skill; //角色的技能

    //方法部分
    function __construct($name,$sex,$skill) //构造方法,自动执行
    {
       $this->role_name = $name; //将参数传进来,给“姓名”属性一个初始值
       $this->role_sex = $sex; //将参数传进来,给“性别”属性一个初始值
       $this->role_skill = $skill; //将参数传进来,给“技能”属性一个初始值

       echo $this->role_name.'横空出世了<br /><br />'; //如果这句话被输出,说明构造方法自动执行了
    }

    function roleTalk() //角色说话
    {
        echo $this->role_name.'说:'.'我是一个'.$this->role_sex.'人<br />'; //输出:(角色的名字)说:我是一个(角色的性别)人
    }

    function roleFight() //角色发招
    {
        echo $this->role_name.'使出了一招:'.$this->role_skill.'<br  /><br />'; //输出:(角色的名字)使出了一招(角色的技能)
    }

    function __destruct() //析构方法,自动执行
    {
         echo $this->role_name.'打完收招,只见天上的浮云组成了一个“纯”字'; //如果这句话被输出,说明析构方法自动执行了
    }
}

//实例化一个对象,同时将构造方法所需要的参数传入
$brother_chun = new Role('春哥','男','霸气菊花残');

//属性设置(因为我们我们已经在构造方法中给了属性初始值,所以不需要设置了)

//访问方法
$brother_chun->roleTalk();
$brother_chun->roleFight();

运行后我们可以得到以下结果:

春哥横空出世了

春哥说:我是一个男人
春哥使出了一招:霸气菊花残

春哥打完收招,只见天上的浮云组成了一个“纯”字

好啦,构造函数和析构函数我们就玩到这里!

作者:hetty 首发地址:http://www.im286.com/thread-4823948-1-1.html

15 七, 2010

php面向对象OOP编程教程(四) - 类的访问

Posted by: kinglife In: php

好,今天我们要玩的东西比较多,所以要集中精力哦.我们已经通过将类实例化来创建了”春哥”、”曾哥”和”凤姐”,但是他们还不能说话、还不能发招,怎么办呢?这就需要我们通过访问类的内容来实现.所谓访问,也是个专业术语,为了方便大家记忆和理解,大家只需要记住:

我们要使用“春哥”的特性,实际上就是要访问“春哥”的属性
我们要使用“春哥”的行为,实际上就是要访问“春哥”的方法

从类的内部访问属性和方法,我们要用this关键字

访问属性:

$this->属性的名称;

设置属性值(其实跟变量赋值是一个道理):

$this->属性的名称 = 属性的值;

访问方法:

$this->方法的名称();

从类的外部访问属性和方法,我们要使用对象的名称

访问属性:

$对象的名称->属性的名称;

设置属性值(其实跟变量赋值是一个道理):

$对象的名称->属性的名称 = 属性的值;

访问方法:

$对象的名称->方法的名称();

注意:在访问时,属性的名称是不带$号的,这一点,在《PHP 和 MySQL Web开发》(第三版)一书中的有些例子是错误的,虽然这本书被称为PHP的“圣经”,但是无论什么样书都难免出现人为的失误,所谓人非圣贤,孰能无过?所以俗话说尽信书不如无书,同样的提醒正在看我这篇教程的初学者们,尽信我不如无我,最重要的还是要大家自己去思考,培养独立思考的能力,不是吗?

光看上面的内容可能很难看出什么来,这很正常,没有关系,下面我们马上通过实例来说明它们的作用。

首先我们完善角色类,让它拥有一切比较实际的功能,这时,我们就要用到内部访问来修改它了:

class Role //角色类
{
    //属性部分
    var $role_name; //角色的名字
    var $role_sex; //角色的性别
    var $role_skill; //角色的技能

    //方法部分
    function roleTalk() //角色说话
    {
        echo $this->role_name.'说:'.'我是一个'.$this->role_sex.'人<br />'; //输出:(角色的名字)说:我是一个(角色的性别)人
    }

    function roleFight() //角色发招
    {
        echo $this->role_name.'使出了一招:'.$this->role_skill.'<br />'; //输出:(角色的名字)使出了一招:(角色的技能)
    }
}

为了方便讲解,每个方法里我只用了一个echo作为它的功能。当然如果你有时间和精力的话,可以去做一些更为复杂强大的功能。

接下来,如果我们要让“春哥”这个对象“活”起来,那么就要用外部访问了:

//别忘了要一定先new一个名称为brother_chun的对象哦
$brother_chun = new Role();

//设置属性
$brother_chun->role_name = '春哥'; //设置“春哥”的名字
$brother_chun->role_sex = '男'; //设置“春哥”的性别
$brother_chun->role_skill = '霸气菊花残'; //设置“春哥”的技能

//访问方法
$brother_chun->roleTalk(); //让“春哥”说话
$brother_chun->roleFight(); //让“春哥”发招

同理于“曾哥”和“凤姐”,为了方便大家查看,给出完整代码:

class Role //角色类
{
    //属性部分
    var $role_name; //角色的名字
    var $role_sex; //角色的性别
    var $role_skill; //角色的技能

    //方法部分
    function roleTalk() //角色说话
    {
        echo $this->role_name.'说:'.'我是一个'.$this->role_sex.'人<br  />'; //输出:(角色的名字)说:我是一个(角色的性别)人
    }

    function roleFight() //角色发招
    {
        echo $this->role_name.'使出了一招:'.$this->role_skill.'<br /><br />'; //输出:(角色的名字)使出了一招(角色的技能)
    }
}

//“春哥”横空出世
$brother_chun = new Role();
//设置属性
$brother_chun->role_name = '春哥';
$brother_chun->role_sex = '男';
$brother_chun->role_skill = '霸气菊花残';
//访问方法
$brother_chun->roleTalk();
$brother_chun->roleFight();

//“曾哥”横空出世
$brother_zeng = new Role();
//设置属性
$brother_zeng ->role_name = '曾哥';
$brother_zeng ->role_sex = '男';
$brother_zeng ->role_skill = '爷们菊花劫';
//访问方法
$brother_zeng ->roleTalk();
$brother_zeng ->roleFight();

//“凤姐”横空出世
$sister_feng = new Role();
//设置属性
$sister_feng ->role_name = '凤姐';
$sister_feng ->role_sex = '女';
$sister_feng ->role_skill = '知音故事会';
//访问方法
$sister_feng ->roleTalk();
$sister_feng ->roleFight();

春哥说:我是一个男人
春哥使出了一招:霸气菊花残

曾哥说:我是一个男人
曾哥使出了一招:绵阳菊花劫

凤姐说:我是一个女人
凤姐使出了一招:知音故事会

以此类推,你还可以让更多的人横空出世,让它们有不同的名字、不同的性别、不同的技能。

你也可以给它们加上其他的属性:比如攻击力、防御力、生命值、霸气值等等;
或者加上给它们加上其他的方法:比如会唱歌、会跳舞、会吃饭、会便便等等。

在这里由于时间和篇幅的关系,我们就不玩那么多了,大家要是有兴趣的话,自己下去慢慢玩吧。

这里着重讲一下this关键字的涵义,this顾名思义就是这个的意思,因为是在类的内部,它是被所有对象共用的,所以可以这么理解:这个对象调用了它,它就属于这个对象;哪个对象调用了它,它就属于哪个对象。

比如 $this->role_sex; 这句,“春哥”调用了它,在类的内部它就指“春哥”这个对象的性别;“曾哥”调用了它,在类的内部它就指“曾哥”这个对象的性别;“凤姐”调用了它,在类的内部它就指“凤姐”这个对象的性别,同理于其他。

好了,那么关于类最基本的玩法就介绍到这里,希望大家能够花一些宝贵的时间来慢慢消化一下今天我们玩过的东东。一定要好好消化哦,因为从下一玩开始,我们就要逐渐进入类的高级玩法了。

作者:hetty 首发地址:http://www.im286.com/thread-4823948-1-1.html

Flickr PhotoStream

    flickrRSS probably needs to be setup

About

Name:KingLife
Email:lifewz#163.com