11<?xml version =" 1.0" encoding =" utf-8" ?>
22<!-- $Revision$ -->
3- <!-- EN-Revision: 9ee9eccf455188ab6eb352194eb6f9eb99e15606 Maintainer: hirokawa Status: ready -->
3+ <!-- EN-Revision: 984188eb6941dc419f49eed6c1a55a6b749a823d Maintainer: hirokawa Status: ready -->
44<!-- CREDITS: shimooka -->
55
66<sect1 xml : id =" language.oop5.abstract" xmlns =" http://docbook.org/ns/docbook" >
77 <title >クラスの抽象化</title >
88
99 <para >
10- PHP には、抽象クラスと抽象メソッドの機能があります。
11- abstract として定義されたクラスのインスタンスを生成することはできません。
12- 1つ以上の抽象メソッドを含む全てのクラスもまた抽象クラスとなります。
13- abstract として定義されたメソッドは、そのメソッドのシグネチャを宣言するのみで、
14- 実装を定義することはできません。
10+ PHP には、抽象クラス、抽象メソッド、抽象プロパティがあります。
11+ abstract として定義された抽象クラスのインスタンスを生成することはできず、
12+ 1つ以上の抽象メソッドや抽象プロパティを含むクラスは抽象クラスでなければいけません。
13+ abstract として定義されたメソッドは、そのメソッドのシグネチャと public または protected のアクセス権を宣言するのみで、
14+ 実装を定義することはできません。抽象プロパティは、
15+ <literal >get</literal > や <literal >set</literal > の要件を宣言することができ、
16+ 実装はどちらか一方に対してのみ行えます。両方同時に実装することはできません。
1517 </para >
1618
1719 <para >
2123 <link linkend =" language.oop.lsp" >シグネチャの互換性に関するルール</link > に従わなければいけません。
2224 </para >
2325
26+ <simpara >
27+ PHP 8.4 から、抽象クラスは public または protected の抽象プロパティを宣言できるようになりました。
28+ protected な抽象プロパティは、protected または public のスコープから読み書き可能なプロパティにより
29+ 要件が満たされます。
30+ </simpara >
31+ <simpara >
32+ 抽象プロパティは、通常のプロパティによって、または
33+ 必要な操作に対応した <link linkend =" language.oop5.property-hooks" >フック</link > を定義したプロパティにより要件が満たされます。
34+ </simpara >
35+
2436 <example >
25- <title >抽象クラスの例 </title >
37+ <title >抽象メソッドの例 </title >
2638 <programlisting role =" php" >
2739<![CDATA[
2840<?php
41+
2942abstract class AbstractClass
3043{
3144 // 拡張クラスにこのメソッドの定義を強制する
3245 abstract protected function getValue();
3346 abstract protected function prefixValue($prefix);
3447
3548 // Common method
36- public function printOut() {
49+ public function printOut()
50+ {
3751 print $this->getValue() . "\n";
3852 }
3953}
4054
4155class ConcreteClass1 extends AbstractClass
4256{
43- protected function getValue() {
57+ protected function getValue()
58+ {
4459 return "ConcreteClass1";
4560 }
4661
47- public function prefixValue($prefix) {
62+ public function prefixValue($prefix)
63+ {
4864 return "{$prefix}ConcreteClass1";
4965 }
5066}
5167
5268class ConcreteClass2 extends AbstractClass
5369{
54- public function getValue() {
70+ public function getValue()
71+ {
5572 return "ConcreteClass2";
5673 }
5774
58- public function prefixValue($prefix) {
75+ public function prefixValue($prefix)
76+ {
5977 return "{$prefix}ConcreteClass2";
6078 }
6179}
6280
63- $class1 = new ConcreteClass1;
81+ $class1 = new ConcreteClass1() ;
6482$class1->printOut();
65- echo $class1->prefixValue('FOO_') . "\n";
83+ echo $class1->prefixValue('FOO_'), "\n";
6684
67- $class2 = new ConcreteClass2;
85+ $class2 = new ConcreteClass2() ;
6886$class2->printOut();
69- echo $class2->prefixValue('FOO_') ."\n";
87+ echo $class2->prefixValue('FOO_'), "\n";
88+
7089?>
7190]]>
7291 </programlisting >
@@ -82,36 +101,38 @@ FOO_ConcreteClass2
82101 </example >
83102
84103 <example >
85- <title >抽象クラスの例 </title >
104+ <title >抽象メソッドの例 </title >
86105 <programlisting role =" php" >
87106<![CDATA[
88107<?php
108+
89109abstract class AbstractClass
90110{
91111 // 抽象メソッドでは、必須の引数だけを定義しています
92112 abstract protected function prefixName($name);
93-
94113}
95114
96115class ConcreteClass extends AbstractClass
97116{
98-
99117 // 子クラスでは、親のシグネチャにないオプション引数を定義することもあるでしょう
100- public function prefixName($name, $separator = ".") {
118+ public function prefixName($name, $separator = ".")
119+ {
101120 if ($name == "Pacman") {
102121 $prefix = "Mr";
103122 } elseif ($name == "Pacwoman") {
104123 $prefix = "Mrs";
105124 } else {
106125 $prefix = "";
107126 }
127+
108128 return "{$prefix}{$separator} {$name}";
109129 }
110130}
111131
112- $class = new ConcreteClass;
132+ $class = new ConcreteClass() ;
113133echo $class->prefixName("Pacman"), "\n";
114134echo $class->prefixName("Pacwoman"), "\n";
135+
115136?>
116137]]>
117138 </programlisting >
@@ -123,9 +144,81 @@ Mrs. Pacwoman
123144]]>
124145 </screen >
125146 </example >
147+ <example >
148+ <title >抽象プロパティの例</title >
149+ <programlisting role =" php" >
150+ <![CDATA[
151+ <?php
126152
127- </sect1 >
153+ abstract class A
154+ {
155+ // 継承するクラスは、public に読み取り可能なプロパティを持たなければなりません
156+ abstract public string $readable {
157+ get;
158+ }
159+
160+ // 継承するクラスは、protected または public に書き込み可能なプロパティを持たなければなりません
161+ abstract protected string $writeable {
162+ set;
163+ }
164+
165+ // 継承するクラスは、protected または public で読み書き可能なプロパティを持たなければなりません
166+ abstract protected string $both {
167+ get;
168+ set;
169+ }
170+ }
171+
172+ class C extends A
173+ {
174+ // 要件を満たし、さらに書き込みも可能にしているため有効です
175+ public string $readable;
176+
177+ // public に読み取り可能でないため、要件を満たしません
178+ protected string $readable;
128179
180+ // 要件を正確に満たしているため有効です
181+ // protected のスコープからのみ書き込みが可能です
182+ protected string $writeable {
183+ set => $value;
184+ }
185+
186+ // protected から public にアクセス権を拡張しており、問題ありません
187+ public string $both;
188+ }
189+
190+ ?>
191+ ]]>
192+ </programlisting >
193+ </example >
194+ <simpara >
195+ 抽象プロパティにはフックを実装できます。
196+ 前の例のように、<literal >get</literal > または <literal >set</literal > のどちらかを、定義せず宣言のみ行います。
197+ </simpara >
198+ <example >
199+ <title >抽象プロパティの例</title >
200+ <programlisting role =" php" >
201+ <![CDATA[
202+ <?php
203+
204+ abstract class A
205+ {
206+ // set のデフォルト実装(オーバーライド可能)を提供し、
207+ // 子クラスが get を実装するよう要求しています
208+ abstract public string $foo {
209+ get;
210+
211+ set {
212+ $this->foo = $value;
213+ }
214+ }
215+ }
216+
217+ ?>
218+ ]]>
219+ </programlisting >
220+ </example >
221+ </sect1 >
129222<!-- Keep this comment at the end of the file
130223Local variables:
131224mode: sgml
0 commit comments