為什麼這篇inherit三態鄉民發文收入到精華區:因為在inherit三態這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!發信人[email protected] (打混的蟑螂史巴克),看板Mud標 題[蟑螂賀...
inherit三態 在 雷克 布 Instagram 的最佳解答
2020-12-04 14:47:01
[ 達摩樂隊 七佛滅罪真言單曲發行台中專場]主視覺設計 達摩樂隊可能是全球首支以歌頌佛學經文為主的金屬樂隊,以推廣佛學文化為宗旨宣揚良善本性為依歸。 樂隊成員來自台灣與加拿大,歌曲創作使用之經文以梵文為主、中文為輔,樂隊創作過程ㄧ切如法並均為歸依三寶的佛弟子。 達摩樂隊用極速的節拍表佛的悲...
基礎 LPC
作者: Descartes of Borg
第一版: 23 april 1993
第二版: 01 july 1993
第五章: 基礎的繼承 (inheritance)
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 的功能一樣.
譯者:
Spock of Final Frontier 98.Jan.25.
--
Boldly go where no mudder has gone before...
Spock (roach admin) 蟑螂管理員
homepage: http://bbs.csmc.edu.tw/spock/
From The Final Frontier 140.128.136.12 4000
※ 來源:‧中山醫學院BBS -- 絮情小站 bbs.csmc.edu.tw‧[FROM: localhost]