blob: 46bf3387f04cba74c119b925979dadbcc47d25d7 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001CONCEPT
2 Inheritance
3
4DESCRIPTION
5 Have you noticed how many objects in the system have the same
6 functionality in common? Let's look at rooms for instance, they
7 all have the ability to host people and provide commands. It's
8 not that every room is programmed with the same basic functions
9 again and again, rather it will use a model room and then make
10 some special changes to it. That doesn't work by copying the
11 file.. Ouch! Don't replicate code! But by putting a tiny inherit
12 declaration
13
14 inherit "<model-class>";
15
16 at the beginning of your new file. This must come before any local
17 ariables or functions. Once inherited your class will behave just
18 like the model class, because all the public methods are available
19 to the outside world. Now it is in your hands to change such an
20 inherited behaviour. You have the following tools to do so:
21
22 * Access to variables
23
24 It is one of the best design decisions in LPC that variables
25 are not accessible from outside, but you can use inherited
26 variables just as if they were your own. Modifiers apply however.
27
28 * Method overloading
29
30 int method_that_also_exists_in_the_model() {
31 <your new code>
32 }
33
34 You can simply rewrite a method that is also defined in the model
35 class, and thus change how it behaves. Contrary to other languages
36 in LPC method overloading only matches the name of the method, so
37 even by changing the amount and type of parameters you will mask
38 out the original version of the method. You can even apply other
39 modifiers to it as the original.
40
41 * Calling inherited methods
42
43 int method_that_also_exists_in_the_model() {
44 <your new code>
45 return ::method_that_also_exists_in_the_model();
46 }
47
48 You can add to the behaviour of a method by redefining it,
49 then calling it from within your new version. You can actually
50 call inherited methods from anywhere in your code. The double
51 colon tells the compiler you are looking for the inherited
52 variant.
53
54EXAMPLE
55
56 Let's imagine very simple food in a file called "/the/food.c":
57
58 // unless "modified" variables are accessible by inheritors
59 int vitamins = 10;
60
61 // please overload this function with your own description
62 public short() { return "something edible"; }
63
64 // let's do some standard action for food
65 public consume() {
66 this_player() -> nourish(vitamins);
67 destruct(this_object());
68 }
69
70 And now someone else decides to do some italian cooking in a
71 file called "/the/fusilli.c"
72
73 inherit "/the/food";
74
75 // we have our own variables.
76 int gone_cold = 0;
77
78 // and we simply redefine the short() function to replace it
79 public short() {
80 // description changes depending on gone_cold
81 return "a "+( gone_cold ? "stinking" : "steaming" )
82 +" plate of fusilli";
83 }
84
85 // we have a new function to make food go cold
86 private deteriorate() {
87 gone_cold = 1;
88 write("The fusilli have gone cold.\n");
89 }
90
91 // assume this gets called at creation
92 private create() {
93 // we can access the variable we inherited from food.c
94 vitamins = 44; // tomato has plenty of vitamins
95
96 // go cold in 5 minutes
97 call_out( #'deteriorate, 5 * 60 );
98 }
99
100 // we can overload the function even with new parameters
101 public consume(how) {
102 // fetch the name of the person, or use "Someone"
103 string name = this_player() -> name() || "Someone";
104
105 if (!gone_cold) {
106 write("You enjoy a delicious plate of fusilli.\n");
107 say(name +" guzzles a plate of hot fusilli.\n");
108 }
109 else if (how == "quickly") {
110 write("You eat the fusilli so quickly you "
111 "hardly notice they have gone cold.\n");
112 say(name +" wolfs down a plate of cold fusilli.\n");
113 }
114 else {
115 write("You eye the plate and wonder if you "
116 "really feel like eating cold fusilli.\n");
117 return; // don't eat
118 }
119
120 // and here comes the most important part:
121 // we execute consume() from food.c, so we
122 // actually inherit its behaviour.
123 ::consume();
124 }
125
126ADVANCED USAGE
127
128 * Doing multiple inheritance
129
130 While the Java(TM) language has so-called interfaces as a kludge,
131 LPC doesn't need them as it supports real multiple inheritance.
132 A very powerful feature, it lets you combine the behaviour of
133 several classes into a new one. Simply put several lines of
134 inherit declarations underneath each other. If you have name
135 collisions in the namespace of inherited methods, you will have
136 to address them explicitely with a "the/file"::method(args) syntax.
137
138 * Wildcarded multiple inheritance
139
140 LDMUD 3.2.1@117 introduces an advanced voodoo syntax which allows
141 you to call several methods in model classes at once, but for some
142 technical reasons it cannot pass any arguments. This works by
143 writing a glob type match ('*' and '?' wildcards) into the string
144 in front of the double colon, as in "*"::create(). I wouldn't
145 recommend you to use this, it's better to be clearly conscious of
146 what you inherit and do. But if you're desperate, there you go.
147
148ADVANCED EXAMPLE
149
150 inherit "foo";
151 inherit "bar";
152 inherit "baz";
153 inherit "ball";
154
155 reset() {
156 "ba?"::reset();
157 // calls bar::reset() and baz::reset()
158
159 "ba*"::reset();
160 // calls bar::reset(), baz::reset() and ball::reset()
161
162 "*"::reset();
163 // calls every inherited reset() function.
164
165 "ball"::rejoice("Listen to italectro today!");
166 // only explicit filename of model class allows
167 // passing arguments to the inherited method
168 }
169
170AUTHOR
171 symlynX of PSYC and Nemesis, with a little help from Someone
172
173SEE ALSO
174 functions(LPC), initialisation(LPC), modifiers(LPC), pragma(LPC),
175 overloading(C)
176 function_exists(efun), functionlist(efun), inherit_list(efun),
177 symbol_variable(efun), variable_exists(efun), variable_list(efun).