注册 登录 查询

迷你方式显示论坛 RSS订阅此版新信息  
首页 >> 论坛 >> ┈┋MUD 交流区┋┈ >> 梦幻泥潭 >> 查看帖子
 新帖 新投票 讨论区 精华区 上篇 刷新 平板 下篇


 帖子主题: LPC教学手册
 
头衔 小混混

离线

ivy
门派 秋林拾叶
职务 总舵主
人物等级 炉火纯青
江湖威望 +8
江湖阅历 30
门派贡献 1507
实战经验 22561
文章 534
注册 05-01-09 22:36
发表 2007-04-12 17:48:56 人气:407

LPC的基础继承

5.1 回顾

你现在应该了解函式基本的功能. 你应该可以宣告并呼叫一个函式. 另外, 你应该能认识函式定义, 虽然你可能是第一次接触 LPC. 你现在并不见得能定义你自 己的函式. 函式是 LPC 物件的基石. 函式中的程式码, 要别的函式呼叫它们的 时候才会执行. 呼叫一个函式时, 作出呼叫的函式要给它输入值, 才能执行被呼叫的函式. 被呼叫的函式执行其程式码, 并传回某种资料型态的传回值给呼叫它 的函式. 没有传回值的函式属於无传回值 (void) 型态.

仔细看过你自己的工作室程式码之后, 它看起来大概像这样 (视 mudlib 而定):

-----

inherit "/std/room";

void create() {

::create();

set_property("light", 2);

set_property("indoors", 1);

set("short", "Descartes 的工作室");

set("long", "此处是 Descartes 工作的地方.\n这裡是一个立方体.\n");

set_exits( ({ "/d/standard/square" }), ({ "square" }) );

}

-----

如果你到目前為止, 所有的课本内容都了解的话, 你应该能认出以下的程式码:

1) create() 是函式的定义. (嘿 ! 他没有宣告它)

2) 它呼叫 set_property() 、set()、set_exits(), 没有一个函式在这段

程式码中曾有宣告或定义.

3) 最上面有一行, 不是宣告变数或函式, 也不是函式定义 !

这一章会找出这些问题的解答, 你现在应该脑中应该有这些问题:

1) 為什麼没有宣告 create() ?

2) 為什麼 set_property() 、set() 、set_exits() 已经宣告并定义过了 ?

3) 档案最上面那一行到底是啥东西 ?

5.2 物件导向程式设计 (object oriented programming, OOP)

继承 (inheritance) 是定义真正物件导向程式设计的特性之一. 它让你创造通 用的程式码, 能以多种用途用於许多不同的程式中. 一个 mudlib 所作的, 就是 创造这些通用的档案 (物件) , 让你用来製造特定物件.

如果你必须把定义前面工作室全部所需要的程式码写出来, 你大概必须要写 1000 行程式码才能得到一个房间所有的功能. 当然, 那根本是浪费磁碟空间. 再者, 这种程式码与玩家和其他房间的互动性很差, 因為每一个创造者都写出自己的函式以作出一个房间的功能. 所以, 你可能使用 query_long() 写出房间的长叙述 , 其他的巫师可能使用 long() . 这就是 mudlib 彼此不相容最主要的原因, 因為它们使用不同的物件互动协定.

OOP 克服了这些问题. 前面的工作室中, 你继承已经定义在 "/std/room.c" 档案 中的函式. 它拥有普通房间所需要的全部函式定义其中. 当你要製造一个特定的 房间, 你拿这个房间档案中定义好的通用函式功能, 并加上你自己的函式 create() 以製造一个独特的房间.

5.3 继承如何作用

你现在大概猜得出来, 这一行:

-----

inherit "/std/room";

-----

让你继承 "std/room.c" 的函式功能. 藉由继承函式功能, 它代表你可以使用 "/std/room.c" 裡面已经宣告并定义好的函式. 在 Nightmare Mudlib 中, "/std/room.c" 裡面有许多函式, 其中有 set_property() 、set() 、 set_exits() 函式, 都已经宣告并定义过. 在你的 creat() 函式裡, 你呼叫那 些函式来设定你房间一开始的值. 这些值让你的房间不同於别的房间, 却保留与记忆体中其他房间互动的能力.

实际的写作中, 每一个 mudlib 都不同, 所以要你使用不同一套的标準函式来达到相同的功能. 说明有哪些函式存在和它们是作什麼用的, 已经超出了这本课本 的范围. 如果你的 mudlib 有自己详细的说明资料, 你会找到教你如何使用各种 继承档案的说明文件以创造物件. 这些说明应该会告诉你有哪些函式、它们需要哪些输入、它们输出的资料型态、以及它们的功能.

5.4 本章总结

本章距离完整解释继承如此复杂的主题还有一大段距离. 本文的目的只是让你能 了解如何使用继承来创造你的物件. 以后的课本将对此会有完整的讨论. 现在你应该已经了解底下几点:

1) 每一个 mudlib 都有一套通用物件库, 有它们自己的通用函式. 创造者 透过继承使用它们, 让撰写物件程式码这件工作更轻鬆, 并与其他物件之间能良 好互动.

2) 可被继承的档案裡头的函式, 每个 mudlib 都不一样. 你的 mud 裡应该有说明文件解释如何使用这些可被继承的档案. 如果你还不知道有哪 些函式可用, 那你就没有办法用它们. 任何时候, 都请你特别注意输入 和输出的资料型态.

3) 你藉由底下这行继承函式的功能:

inherit "filename";

-----

filename 是被继承的物件档案名称. 这行放在你程式码的开头.

註解:

你可能看到有几处地方有 ::create() 或 ::init() 或 ::reset() 语法. 你现在不需要完全了解这个, 但是应该告诉你一点线索, 知道它到底是什麼. 「::」运算子是一种特殊的方法来呼叫继承物件的函式 (叫做范围解析运算子 scope resolution operator). 例如, 大多数 mud 的 room.c 都有叫做 create() 的 函式. 当你继承 room.c 并设定 create() 时, 你所作的事称為超越 (override) room.c 的 create() 函式. 这表示不管任何东西呼叫你房间的 create() , 它 会呼叫「你的」版本, 而不是 room.c 裡面的那一个. :: 运算子让你能呼叫 room.c 裡的 create() 而不是你的 create().

一个例子:

-----

#1

inherit "/std/room";

void create() { create(); }

-----

-----

<>
#2

inherit "/std/room";

void create() { ::create(); }

-----

第一个例子是个恐怖的例子. 当它被载入时, driver 呼叫 create() , 之后 create() 再呼叫 create(), create() 又呼叫 create(), 这时 create() 又 呼叫 create()......换句话说, 所有的 create() 就一直呼叫自己直到 driver 侦测到太深的递迴 (recursion) 并跳出来.

第二个例子基本上只是浪费记忆体, 它的功能跟 room.c 没有两样. 对它而言, driver 先呼叫它的 room.c , 然后呼叫 ::create() , 也就是 room.c 裡的 create() . 其他的地方就跟 room.c 的功能一样.


点击这里给我发消息
相关帖子
LPC教学手册 (ivy,5158,2007-04-12 17:41:06)
    LPC基本简介 (ivy,769,2007-04-12 17:43:36)
    LPC的资料型态 (ivy,496,2007-04-12 17:45:51)
    LPC的函式 (ivy,571,2007-04-12 17:47:08)
    LPC的基础继承 (ivy,407,2007-04-12 17:48:56)
    LPC的变数处理 (ivy,343,2007-04-12 17:49:51)
    LPC的流程控制 (ivy,413,2007-04-12 17:52:24)
    LPC的物件资料型态 (ivy,542,2007-04-12 17:53:16)
    好复杂啊。。。。 (gfdsa1,316,2007-05-20 04:00:57)