blob: 127b7e6c456adf8a54f8cbfb8fc7349ead434154 [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
Zesstra7ea4a032019-11-26 20:11:40 +010013
MG Mud User88f12472016-06-24 23:31:02 +020014 inherit "<model-class>";
Zesstra7ea4a032019-11-26 20:11:40 +010015
MG Mud User88f12472016-06-24 23:31:02 +020016 at the beginning of your new file. This must come before any local
Zesstra7ea4a032019-11-26 20:11:40 +010017 variables or functions. Once inherited your class will behave just
MG Mud User88f12472016-06-24 23:31:02 +020018 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
MG Mud User88f12472016-06-24 23:31:02 +020055 Let's imagine very simple food in a file called "/the/food.c":
56
57 // unless "modified" variables are accessible by inheritors
58 int vitamins = 10;
59
60 // please overload this function with your own description
61 public short() { return "something edible"; }
62
63 // let's do some standard action for food
64 public consume() {
65 this_player() -> nourish(vitamins);
66 destruct(this_object());
67 }
68
69 And now someone else decides to do some italian cooking in a
70 file called "/the/fusilli.c"
71
72 inherit "/the/food";
73
74 // we have our own variables.
75 int gone_cold = 0;
76
77 // and we simply redefine the short() function to replace it
78 public short() {
79 // description changes depending on gone_cold
80 return "a "+( gone_cold ? "stinking" : "steaming" )
81 +" plate of fusilli";
82 }
83
84 // we have a new function to make food go cold
85 private deteriorate() {
86 gone_cold = 1;
87 write("The fusilli have gone cold.\n");
88 }
89
90 // assume this gets called at creation
91 private create() {
92 // we can access the variable we inherited from food.c
93 vitamins = 44; // tomato has plenty of vitamins
94
95 // go cold in 5 minutes
96 call_out( #'deteriorate, 5 * 60 );
97 }
98
99 // we can overload the function even with new parameters
100 public consume(how) {
101 // fetch the name of the person, or use "Someone"
102 string name = this_player() -> name() || "Someone";
103
104 if (!gone_cold) {
105 write("You enjoy a delicious plate of fusilli.\n");
106 say(name +" guzzles a plate of hot fusilli.\n");
107 }
108 else if (how == "quickly") {
109 write("You eat the fusilli so quickly you "
110 "hardly notice they have gone cold.\n");
111 say(name +" wolfs down a plate of cold fusilli.\n");
112 }
113 else {
114 write("You eye the plate and wonder if you "
115 "really feel like eating cold fusilli.\n");
116 return; // don't eat
117 }
118
119 // and here comes the most important part:
120 // we execute consume() from food.c, so we
121 // actually inherit its behaviour.
122 ::consume();
123 }
124
125ADVANCED USAGE
MG Mud User88f12472016-06-24 23:31:02 +0200126 * Doing multiple inheritance
127
128 While the Java(TM) language has so-called interfaces as a kludge,
129 LPC doesn't need them as it supports real multiple inheritance.
130 A very powerful feature, it lets you combine the behaviour of
131 several classes into a new one. Simply put several lines of
132 inherit declarations underneath each other. If you have name
133 collisions in the namespace of inherited methods, you will have
134 to address them explicitely with a "the/file"::method(args) syntax.
135
136 * Wildcarded multiple inheritance
137
Zesstra7ea4a032019-11-26 20:11:40 +0100138 LDMud 3.2.1@117 introduces an advanced voodoo syntax which allows
139 you to call several methods in model classes at once. This works by
MG Mud User88f12472016-06-24 23:31:02 +0200140 writing a glob type match ('*' and '?' wildcards) into the string
Zesstra7ea4a032019-11-26 20:11:40 +0100141 in front of the double colon, as in "*"::create().
142 I wouldn't recommend you to use this, it's better to be clearly
143 conscious of what you inherit and do. But if you're desperate, there
144 you go.
145
146 Since LDMud 3.5.0 it is possible to pass arguments as well.
MG Mud User88f12472016-06-24 23:31:02 +0200147
148ADVANCED EXAMPLE
MG Mud User88f12472016-06-24 23:31:02 +0200149 inherit "foo";
150 inherit "bar";
151 inherit "baz";
152 inherit "ball";
153
154 reset() {
155 "ba?"::reset();
156 // calls bar::reset() and baz::reset()
157
158 "ba*"::reset();
159 // calls bar::reset(), baz::reset() and ball::reset()
160
161 "*"::reset();
162 // calls every inherited reset() function.
163
164 "ball"::rejoice("Listen to italectro today!");
165 // only explicit filename of model class allows
166 // passing arguments to the inherited method
167 }
168
169AUTHOR
170 symlynX of PSYC and Nemesis, with a little help from Someone
171
172SEE ALSO
173 functions(LPC), initialisation(LPC), modifiers(LPC), pragma(LPC),
Zesstra7ea4a032019-11-26 20:11:40 +0100174 overloading(C),
175 function_exists(E), functionlist(E), inherit_list(E),
176 symbol_variable(E), variable_exists(E), variable_list(E)