1
1
<?xml version =" 1.0" encoding =" utf-8" ?>
2
2
<!-- $Revision$ -->
3
- <!-- EN-Revision: 7341710fa635b4a969bc855a1e4619cdfa6b63f1 Maintainer: takagi Status: ready -->
3
+ <!-- EN-Revision: c1f37a6c270aadbbb3da56a3973ffd62197adf2b Maintainer: takagi Status: ready -->
4
4
<!-- CREDITS: mumumu -->
5
5
6
6
<sect1 xml : id =" language.oop5.traits" xmlns =" http://docbook.org/ns/docbook" >
26
26
<programlisting role =" php" >
27
27
<![CDATA[
28
28
<?php
29
- trait ezcReflectionReturnInfo {
30
- function getReturnType() { /*1*/ }
31
- function getReturnDescription() { /*2*/ }
29
+
30
+ trait TraitA {
31
+ public function sayHello() {
32
+ echo 'Hello';
33
+ }
32
34
}
33
35
34
- class ezcReflectionMethod extends ReflectionMethod {
35
- use ezcReflectionReturnInfo;
36
- /* ... */
36
+ trait TraitB {
37
+ public function sayWorld() {
38
+ echo 'World';
39
+ }
37
40
}
38
41
39
- class ezcReflectionFunction extends ReflectionFunction {
40
- use ezcReflectionReturnInfo;
41
- /* ... */
42
+ class MyHelloWorld
43
+ {
44
+ use TraitA, TraitB; // A class can use multiple traits
45
+
46
+ public function sayHelloWorld() {
47
+ $this->sayHello();
48
+ echo ' ';
49
+ $this->sayWorld();
50
+ echo "!\n";
51
+ }
42
52
}
53
+
54
+ $myHelloWorld = new MyHelloWorld();
55
+ $myHelloWorld->sayHelloWorld();
56
+
43
57
?>
44
58
]]>
45
59
</programlisting >
60
+ &example.outputs;
61
+ <screen >
62
+ <![CDATA[
63
+ Hello World!
64
+ ]]>
65
+ </screen >
46
66
</example >
47
67
48
68
<sect2 xml : id =" language.oop5.traits.precedence" >
@@ -123,7 +143,7 @@ Hello Universe!
123
143
</screen >
124
144
</example >
125
145
</sect2 >
126
-
146
+
127
147
<sect2 xml : id =" language.oop5.traits.multiple" >
128
148
<title >複数のトレイト</title >
129
149
<para >
@@ -200,7 +220,7 @@ Hello World!
200
220
演算子を使って B の bigTalk の実装に
201
221
<literal >talk</literal > というエイリアスを指定して使います。
202
222
</para >
203
- <programlisting role =" php" >
223
+ <programlisting role =" php" annotations = " non-interactive " >
204
224
<![CDATA[
205
225
<?php
206
226
trait A {
@@ -249,7 +269,7 @@ class Aliased_Talker {
249
269
</para >
250
270
<example xml : id =" language.oop5.traits.visibility.ex1" >
251
271
<title >メソッドのアクセス権を変更する</title >
252
- <programlisting role =" php" >
272
+ <programlisting role =" php" annotations = " non-interactive " >
253
273
<![CDATA[
254
274
<?php
255
275
trait HelloWorld {
@@ -383,67 +403,126 @@ class MyHelloWorld {
383
403
<programlisting role =" php" >
384
404
<![CDATA[
385
405
<?php
386
- trait Counter {
387
- public function inc() {
406
+
407
+ trait Counter
408
+ {
409
+ public function inc()
410
+ {
388
411
static $c = 0;
389
412
$c = $c + 1;
390
413
echo "$c\n";
391
414
}
392
415
}
393
416
394
- class C1 {
417
+ class C1
418
+ {
395
419
use Counter;
396
420
}
397
421
398
- class C2 {
422
+ class C2
423
+ {
399
424
use Counter;
400
425
}
401
426
402
- $o = new C1(); $o->inc(); // 1 と表示
403
- $p = new C2(); $p->inc(); // 1 と表示
427
+ $o = new C1();
428
+ $o->inc();
429
+ $p = new C2();
430
+ $p->inc();
431
+
404
432
?>
405
433
]]>
406
434
</programlisting >
435
+ &example.outputs;
436
+ <screen >
437
+ <![CDATA[
438
+ 1
439
+ 1
440
+ ]]>
441
+ </screen >
407
442
</example >
408
443
<example xml : id =" language.oop5.traits.static.ex2" >
409
444
<title >staticメソッド</title >
410
445
<programlisting role =" php" >
411
446
<![CDATA[
412
447
<?php
413
- trait StaticExample {
414
- public static function doSomething() {
448
+
449
+ trait StaticExample
450
+ {
451
+ public static function doSomething()
452
+ {
415
453
return 'Doing something';
416
454
}
417
455
}
418
456
419
- class Example {
457
+ class Example
458
+ {
420
459
use StaticExample;
421
460
}
422
461
423
- Example::doSomething();
424
- ?>
462
+ echo Example::doSomething();
425
463
464
+ ?>
426
465
]]>
427
466
</programlisting >
467
+ &example.outputs;
468
+ <screen >
469
+ <![CDATA[
470
+ Doing something
471
+ ]]>
472
+ </screen >
428
473
</example >
429
474
<example xml : id =" language.oop5.traits.static.ex3" >
430
475
<title >staticプロパティ</title >
476
+ <caution >
477
+ <simpara >
478
+ PHP 8.3.0 より前のバージョンでは、トレイト中で定義された static プロパティは、
479
+ そのトレイトを use している同じ継承階層にある全てのクラスで共有されていました。
480
+ PHP 8.3.0 以降では、子クラスが static プロパティを持つトレイトを use している場合、
481
+ 親クラスで定義された static プロパティとは別物とみなされるようになりました。
482
+ </simpara >
483
+ </caution >
431
484
<programlisting role =" php" >
432
485
<![CDATA[
433
486
<?php
434
- trait StaticExample {
435
- public static $static = 'foo';
487
+
488
+ trait T
489
+ {
490
+ public static $counter = 1;
436
491
}
437
- class Example {
438
- use StaticExample;
492
+
493
+ class A
494
+ {
495
+ use T;
496
+
497
+ public static function incrementCounter()
498
+ {
499
+ static::$counter++;
500
+ }
439
501
}
440
- echo Example::$static;
502
+
503
+ class B extends A
504
+ {
505
+ use T;
506
+ }
507
+
508
+ A::incrementCounter();
509
+
510
+ echo A::$counter, "\n";
511
+ echo B::$counter, "\n";
512
+
441
513
?>
442
514
]]>
443
515
</programlisting >
516
+ &example.outputs.83;
517
+ <screen >
518
+ <![CDATA[
519
+ 2
520
+ 1
521
+ ]]>
522
+ </screen >
444
523
</example >
445
524
</sect2 >
446
-
525
+
447
526
<sect2 xml : id =" language.oop5.traits.properties" >
448
527
<title >プロパティ</title >
449
528
<para >
@@ -454,16 +533,20 @@ echo Example::$static;
454
533
<programlisting role =" php" >
455
534
<![CDATA[
456
535
<?php
457
- trait PropertiesTrait {
536
+
537
+ trait PropertiesTrait
538
+ {
458
539
public $x = 1;
459
540
}
460
541
461
- class PropertiesExample {
542
+ class PropertiesExample
543
+ {
462
544
use PropertiesTrait;
463
545
}
464
546
465
- $example = new PropertiesExample;
547
+ $example = new PropertiesExample() ;
466
548
$example->x;
549
+
467
550
?>
468
551
]]>
469
552
</programlisting >
@@ -518,10 +601,16 @@ class ConstantsExample {
518
601
}
519
602
520
603
$example = new ConstantsExample;
521
- echo $example::FLAG_MUTABLE; // 1
604
+ echo $example::FLAG_MUTABLE;
522
605
?>
523
606
]]>
524
607
</programlisting >
608
+ &example.outputs;
609
+ <screen >
610
+ <![CDATA[
611
+ 1
612
+ ]]>
613
+ </screen >
525
614
</example >
526
615
<para >
527
616
トレイトで定数を定義したときは、
@@ -548,6 +637,53 @@ class ConstantsExample {
548
637
</example >
549
638
</sect2 >
550
639
640
+ <sect2 xml : id =" language.oop5.traits.final-methods" >
641
+ <title >Final メソッド</title >
642
+ <simpara >
643
+ PHP 8.3.0 以降では、<literal >as</literal > 演算子を使って
644
+ <link linkend =" language.oop5.final" >final</link >
645
+ をトレイトからインポートしたメソッドに適用できるようになりました。
646
+ こうすることで、子クラスでそのメソッドをオーバーライドすることを防止できます。
647
+ しかし、トレイトを使うクラスは、未だそのメソッドをオーバーライドできます。
648
+ </simpara >
649
+ <example xml : id =" language.oop5.traits.final-methods.example" >
650
+ <title >トレイトからインポートするメソッドを <literal >final</literal > として定義する</title >
651
+ <programlisting role =" php" >
652
+ <![CDATA[
653
+ <?php
654
+
655
+ trait CommonTrait
656
+ {
657
+ public function method()
658
+ {
659
+ echo 'Hello';
660
+ }
661
+ }
662
+
663
+ class FinalExampleA
664
+ {
665
+ use CommonTrait {
666
+ CommonTrait::method as final; // The 'final' prevents child classes from overriding the method
667
+ }
668
+ }
669
+
670
+ class FinalExampleB extends FinalExampleA
671
+ {
672
+ public function method() {}
673
+ }
674
+
675
+ ?>
676
+ ]]>
677
+ </programlisting >
678
+ &example.outputs.similar;
679
+ <screen >
680
+ <![CDATA[
681
+ Fatal error: Cannot override final method FinalExampleA::method() in ...
682
+ ]]>
683
+ </screen >
684
+ </example >
685
+ </sect2 >
686
+
551
687
</sect1 >
552
688
553
689
<!-- Keep this comment at the end of the file
0 commit comments