1
1
<?xml version =" 1.0" encoding =" utf-8" ?>
2
2
<!-- $Revision$ -->
3
- <!-- EN-Revision: 9ee9eccf455188ab6eb352194eb6f9eb99e15606 Maintainer: hirokawa Status: ready -->
3
+ <!-- EN-Revision: 984188eb6941dc419f49eed6c1a55a6b749a823d Maintainer: hirokawa Status: ready -->
4
4
<!-- CREDITS: shimooka -->
5
5
6
6
<sect1 xml : id =" language.oop5.abstract" xmlns =" http://docbook.org/ns/docbook" >
7
7
<title >クラスの抽象化</title >
8
8
9
9
<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
+ 実装はどちらか一方に対してのみ行えます。両方同時に実装することはできません。
15
17
</para >
16
18
17
19
<para >
21
23
<link linkend =" language.oop.lsp" >シグネチャの互換性に関するルール</link > に従わなければいけません。
22
24
</para >
23
25
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
+
24
36
<example >
25
- <title >抽象クラスの例 </title >
37
+ <title >抽象メソッドの例 </title >
26
38
<programlisting role =" php" >
27
39
<![CDATA[
28
40
<?php
41
+
29
42
abstract class AbstractClass
30
43
{
31
44
// 拡張クラスにこのメソッドの定義を強制する
32
45
abstract protected function getValue();
33
46
abstract protected function prefixValue($prefix);
34
47
35
48
// Common method
36
- public function printOut() {
49
+ public function printOut()
50
+ {
37
51
print $this->getValue() . "\n";
38
52
}
39
53
}
40
54
41
55
class ConcreteClass1 extends AbstractClass
42
56
{
43
- protected function getValue() {
57
+ protected function getValue()
58
+ {
44
59
return "ConcreteClass1";
45
60
}
46
61
47
- public function prefixValue($prefix) {
62
+ public function prefixValue($prefix)
63
+ {
48
64
return "{$prefix}ConcreteClass1";
49
65
}
50
66
}
51
67
52
68
class ConcreteClass2 extends AbstractClass
53
69
{
54
- public function getValue() {
70
+ public function getValue()
71
+ {
55
72
return "ConcreteClass2";
56
73
}
57
74
58
- public function prefixValue($prefix) {
75
+ public function prefixValue($prefix)
76
+ {
59
77
return "{$prefix}ConcreteClass2";
60
78
}
61
79
}
62
80
63
- $class1 = new ConcreteClass1;
81
+ $class1 = new ConcreteClass1() ;
64
82
$class1->printOut();
65
- echo $class1->prefixValue('FOO_') . "\n";
83
+ echo $class1->prefixValue('FOO_'), "\n";
66
84
67
- $class2 = new ConcreteClass2;
85
+ $class2 = new ConcreteClass2() ;
68
86
$class2->printOut();
69
- echo $class2->prefixValue('FOO_') ."\n";
87
+ echo $class2->prefixValue('FOO_'), "\n";
88
+
70
89
?>
71
90
]]>
72
91
</programlisting >
@@ -82,36 +101,38 @@ FOO_ConcreteClass2
82
101
</example >
83
102
84
103
<example >
85
- <title >抽象クラスの例 </title >
104
+ <title >抽象メソッドの例 </title >
86
105
<programlisting role =" php" >
87
106
<![CDATA[
88
107
<?php
108
+
89
109
abstract class AbstractClass
90
110
{
91
111
// 抽象メソッドでは、必須の引数だけを定義しています
92
112
abstract protected function prefixName($name);
93
-
94
113
}
95
114
96
115
class ConcreteClass extends AbstractClass
97
116
{
98
-
99
117
// 子クラスでは、親のシグネチャにないオプション引数を定義することもあるでしょう
100
- public function prefixName($name, $separator = ".") {
118
+ public function prefixName($name, $separator = ".")
119
+ {
101
120
if ($name == "Pacman") {
102
121
$prefix = "Mr";
103
122
} elseif ($name == "Pacwoman") {
104
123
$prefix = "Mrs";
105
124
} else {
106
125
$prefix = "";
107
126
}
127
+
108
128
return "{$prefix}{$separator} {$name}";
109
129
}
110
130
}
111
131
112
- $class = new ConcreteClass;
132
+ $class = new ConcreteClass() ;
113
133
echo $class->prefixName("Pacman"), "\n";
114
134
echo $class->prefixName("Pacwoman"), "\n";
135
+
115
136
?>
116
137
]]>
117
138
</programlisting >
@@ -123,9 +144,81 @@ Mrs. Pacwoman
123
144
]]>
124
145
</screen >
125
146
</example >
147
+ <example >
148
+ <title >抽象プロパティの例</title >
149
+ <programlisting role =" php" >
150
+ <![CDATA[
151
+ <?php
126
152
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;
128
179
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 >
129
222
<!-- Keep this comment at the end of the file
130
223
Local variables:
131
224
mode: sgml
0 commit comments