|  | | 头衔 小混混 
  
 | 
  ivy
 |  | 门派 秋林拾叶 职务 总舵主
 人物等级 炉火纯青
 江湖威望 +8
 江湖阅历 30
 门派贡献 1507
 实战经验 22561
 文章 534
 注册 05-01-09 22:36
 
 | 
 | |  | 发表 2007-04-12 17:48:56 人气:575    
 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,6309,2007-04-12 17:41:06) |  |  LPC基本简介 (ivy,1111,2007-04-12 17:43:36) |  |  LPC的资料型态 (ivy,680,2007-04-12 17:45:51) |  |  LPC的函式 (ivy,769,2007-04-12 17:47:08) |  |  LPC的基础继承 (ivy,575,2007-04-12 17:48:56) |  |  LPC的变数处理 (ivy,523,2007-04-12 17:49:51) |  |  LPC的流程控制 (ivy,646,2007-04-12 17:52:24) |  |  LPC的物件资料型态 (ivy,710,2007-04-12 17:53:16) |  |  好复杂啊。。。。 (gfdsa1,500,2007-05-20 04:00:57) |  
 | 
 |