@@ -217,7 +217,97 @@ certainly override them.
217
217
218
218
TODO: example
219
219
220
- TODO: object construction, inheritance
220
+ = head2 Inheritance
221
+
222
+ Classes can have I < parent classes > .
223
+
224
+ class Child is Parent1 is Parent2 { }
225
+
226
+ If a method is called on the child class, and the child class does not
227
+ provide that method, the parents' method of the name is invoked instead,
228
+ if it exists. The order by which parent classes are consulted is called the
229
+ I < method resolution order > (mro). Perl 6 uses the
230
+ L < C3 method resolution order|https://en.wikipedia.org/wiki/C3_linearization > .
231
+ You can ask a type for its MRO through a call to its metaclass:
232
+
233
+
234
+ say Parcel.^mro; # Parcel() Cool() Any() Mu()
235
+
236
+ If a class does not specify a parent class, L < Any > is assumed by default. All
237
+ classes directly or indirectly derive from L < Mu > , the root of the type
238
+ hierarchy.
239
+
240
+ All calls to public method are "virtual" in the C++ sense, wihch means that
241
+ the actual type of an object determines which method to call, not the declared
242
+ type.
243
+
244
+ = head2 Object Construction
245
+
246
+ Objects are generally created through methods calls, either on the type object
247
+ or on another object of the same type.
248
+
249
+ Class L < Mu > provides a constructor method called L < new > , which takes named
250
+ arguments and uses them to initialize public attributes.
251
+
252
+ class Point {
253
+ has $.x;
254
+ has $.y = 2 * $!x;
255
+ }
256
+ my $p = Point.new( x => 1, y => 2);
257
+ # ^^^ inherited from class Mu
258
+
259
+ Mu.new calls method L < bless > on its invocant, passing along all the named
260
+ arguments. C < bless > creates the new object, and then calls method C < BUILDALL >
261
+ on it. C < BUILDALL > walks all subclasses in reverse method resolution order
262
+ (ie from L < Mu > to most derived classes), and in each class checks for
263
+ existence of a method named C < BUILD > . If it exists, it is called, again
264
+ passing all named arguments from method C < new > to it. If not, the public
265
+ attributes from this class are initialized from named arguments of the same
266
+ name. In either case, if neither C < BUILD > nor the default mechanism has
267
+ initialized the attribute, default values are applied (the C < 2 * $!x > in the
268
+ example above).
269
+
270
+ This object construction scheme has several implications for customized
271
+ constructors. First, custom C < BUILD > methods should always be submethods,
272
+ otherwise they break attribute initialization in subclasses. Second,
273
+ C < BUILD > submethods can be used to run custom code at object construction
274
+ time. They can also be used for creating aliases for attribute initialization:
275
+
276
+ class EncodedBuffer {
277
+ has $.enc;
278
+ has $.data;
279
+
280
+ submethod BUILD(:encoding(:$enc), :$data) {
281
+ $!enc := $enc;
282
+ $!data := $data;
283
+ }
284
+ }
285
+ my $b1 = EncodedBuffer.new( encoding => 'UTF-8', data => [64, 65] );
286
+ my $b2 = EncodedBuffer.new( enc => 'UTF-8', data => [64, 65] );
287
+ # both enc and encoding are allowed now
288
+
289
+ Since passing arguments to a routine binds the argumenst to the parameters,
290
+ a separate binding step is unnecessary if the attribute is used as parameter.
291
+ So the example above yould also have been written as
292
+
293
+ submethod BUILD(:encoding(:$!enc), :$!data) {
294
+ # nothing to do here anymore, the signature binding
295
+ # does all the work for us.
296
+ }
297
+
298
+ The third implication is that if you want a constructor that accepts positional
299
+ arguments, you must write your own C < new > method:
300
+
301
+ class Point {
302
+ has $.x;
303
+ has $.y;
304
+ method new($x, $y) {
305
+ self.bless(*, :$x, :$y);
306
+ }
307
+ }
308
+
309
+ However this is considered poor practise, because it makes correct
310
+ initialization of objects from subclasses much harder.
221
311
222
312
= head1 Roles
223
313
0 commit comments