11<?xml version =" 1.0" encoding =" utf-8" ?>
22<!-- $Revision$ -->
3- <!-- EN-Revision: f5e5b54129045a7d02c5285a88cea0abff8ffb6f Maintainer: hirokawa Status: ready -->
3+ <!-- EN-Revision: 7d7b378abd302430b8ce7cedb4b78c7033f5e88c Maintainer: hirokawa Status: ready -->
44<!-- CREDITS: takagi,mumumu -->
55
6- <sect1 xml : id =" language.oop5.visibility" xmlns =" http://docbook.org/ns/docbook" >
7- <title >アクセス権</title >
8- <para >
9- プロパティ、メソッドまたは (PHP 7.1.0 以降) 定数のアクセス権 (visibility) は、
10- キーワード: <literal >public</literal >, <literal >protected</literal >
11- または <literal >private</literal > を指定することにより定義できます。
12- public 宣言されたクラスのメンバーには、どこからでもアクセス可能です。
13- protected 宣言されたメンバーには、
14- そのクラス自身、そのクラスを継承したクラス、および親クラスからのみアクセスできます。
15- private 宣言されたメンバーには、そのメンバーを定義したクラスからのみアクセスできます。
16- </para >
6+ <sect1 xml : id =" language.oop5.visibility" xmlns =" http://docbook.org/ns/docbook" >
7+ <title >アクセス権</title >
8+ <para >
9+ プロパティ、メソッドまたは (PHP 7.1.0 以降) 定数のアクセス権 (visibility) は、
10+ キーワード: <literal >public</literal >, <literal >protected</literal >
11+ または <literal >private</literal > を指定することにより定義できます。
12+ public 宣言されたクラスのメンバーには、どこからでもアクセス可能です。
13+ protected 宣言されたメンバーには、
14+ そのクラス自身、そのクラスを継承したクラス、および親クラスからのみアクセスできます。
15+ private 宣言されたメンバーには、そのメンバーを定義したクラスからのみアクセスできます。
16+ </para >
1717
1818 <sect2 xml : id =" language.oop5.visibility-members" >
1919 <title >プロパティのアクセス権</title >
2323 アクセス権を明示的に指定しない場合、
2424 そのプロパティは public として定義されます。
2525 </para >
26- <para >
27- <example >
28- <title >プロパティの宣言</title >
29- <programlisting role =" php" >
26+ <example >
27+ <title >プロパティの宣言</title >
28+ <programlisting role =" php" >
3029<![CDATA[
3130<?php
3231/**
@@ -81,17 +80,135 @@ $obj2->printHello(); // Public2, Protected2, Undefined を表示します
8180]]>
8281 </programlisting >
8382 </example >
84- </para >
85- </sect2 >
83+ <sect3 xml : id =" language.oop5.visibility-members-aviz" >
84+ <title >非対称可視性プロパティ</title >
85+ <simpara >
86+ PHP 8.4 から、プロパティは非対称に
87+ 可視性を設定できるようになりました。
88+ 読み取り(<literal >get</literal >)と書き込み(<literal >set</literal >)に
89+ 異なるスコープを設定できます。具体的には、<literal >set</literal > の可視性が
90+ メインの可視性より広くならない限り、
91+ 別々に指定できます。
92+ </simpara >
93+ <example >
94+ <title >非対称可視性プロパティ</title >
95+ <programlisting role =" php" >
96+ <![CDATA[
97+ <?php
98+ class Book
99+ {
100+ public function __construct(
101+ public private(set) string $title,
102+ public protected(set) string $author,
103+ protected private(set) int $pubYear,
104+ ) {}
105+ }
86106
87- <sect2 xml : id =" language.oop5.visiblity-methods" >
88- <title >メソッドのアクセス権</title >
89- <para >
90- クラスメソッドは、public, private, または protected
91- として定義します。アクセス権を明示せずに宣言したメソッドは、
92- public となります。
93- </para >
94- <para >
107+ class SpecialBook extends Book
108+ {
109+ public function update(string $author, int $year): void
110+ {
111+ $this->author = $author; // OK
112+ $this->pubYear = $year; // 致命的なエラー
113+ }
114+ }
115+
116+ $b = new Book('How to PHP', 'Peter H. Peterson', 2024);
117+
118+ echo $b->title; // OK
119+ echo $b->author; // OK
120+ echo $b->pubYear; // 致命的なエラー
121+
122+ $b->title = 'How not to PHP'; // 致命的なエラー
123+ $b->author = 'Pedro H. Peterson'; // 致命的なエラー
124+ $b->pubYear = 2023; // 致命的なエラー
125+ ?>
126+ ]]>
127+ </programlisting >
128+ </example >
129+ <para >非対称可視性プロパティにはいくつかの注意点があります:</para >
130+ <itemizedlist >
131+ <listitem >
132+ <simpara >
133+ 型付きプロパティのみが、<literal >set</literal > の可視性を個別に指定できます。
134+ </simpara >
135+ </listitem >
136+ <listitem >
137+ <simpara >
138+ <literal >set</literal > の可視性は、<literal >get</literal > と同じか、
139+ より厳しくなければなりません。つまり、
140+ <code >public protected(set)</code > および <code >protected protected(set)</code >
141+ は許可されますが、<code >protected public(set)</code > は構文エラーになります。
142+ </simpara >
143+ </listitem >
144+ <listitem >
145+ <simpara >
146+ プロパティが <literal >public</literal > の場合、メインの可視性は
147+ 省略できます。つまり、<code >public private(set)</code > と <code >private(set)</code > は
148+ 同じ結果になります。
149+ </simpara >
150+ </listitem >
151+ <listitem >
152+ <simpara >
153+ <literal >private(set)</literal > の可視性を持つプロパティは
154+ 自動的に <literal >final</literal > となり、子クラスで再宣言できません。
155+ </simpara >
156+ </listitem >
157+ <listitem >
158+ <simpara >
159+ プロパティへのリファレンスを取得する場合、<literal >get</literal > ではなく <literal >set</literal > の可視性に従います。
160+ これは、リファレンスを使用してプロパティの値を変更できるためです。
161+ </simpara >
162+ </listitem >
163+ <listitem >
164+ <simpara >
165+ 同様に、配列プロパティへの書き込みを試みると、内部的には <literal >get</literal > と
166+ <literal >set</literal > の両方の操作が行われます。そのため、常により厳しい <literal >set</literal >
167+ の可視性に従います。
168+ </simpara >
169+ </listitem >
170+ </itemizedlist >
171+ <simpara >
172+ クラスが別のクラスを拡張するとき、子クラスは
173+ <literal >final</literal > でない任意のプロパティを再定義できます。その際、
174+ 新しい可視性が親クラスと同じか広い場合に限り、メインの可視性または <literal >set</literal >
175+ の可視性を広げることができます。ただし、
176+ <literal >private</literal > プロパティがオーバーライドされると、
177+ 実際には親のプロパティを変更するのではなく、
178+ 異なる内部名を持つ新しいプロパティを作成することに注意してください。
179+ </simpara >
180+ <example >
181+ <title >非対称可視性プロパティの継承</title >
182+ <programlisting role =" php" >
183+ <![CDATA[
184+ <?php
185+ class Book
186+ {
187+ protected string $title;
188+ public protected(set) string $author;
189+ protected private(set) int $pubYear;
190+ }
191+
192+ class SpecialBook extends Book
193+ {
194+ public protected(set) $title; // OK。読み取りの可視性が広く、書き込みは同じだから。
195+ public string $author; // OK。読み取りの可視性は同じで、書き込みが広いから。
196+ public protected(set) int $pubYear; // 致命的なエラー。private(set) プロパティは final です。
197+ }
198+ ?>
199+ ]]>
200+ </programlisting >
201+ </example >
202+ </sect3 >
203+ </sect2 >
204+
205+ <sect2 xml : id =" language.oop5.visiblity-methods" >
206+ <title >メソッドのアクセス権</title >
207+ <para >
208+ クラスメソッドは、public, private, または protected
209+ として定義します。アクセス権を明示せずに宣言したメソッドは、
210+ public となります。
211+ </para >
95212 <example >
96213 <title >メソッドの宣言</title >
97214 <programlisting role =" php" >
@@ -182,8 +299,7 @@ $myFoo->test(); // Bar::testPrivate
182299]]>
183300 </programlisting >
184301 </example >
185- </para >
186- </sect2 >
302+ </sect2 >
187303
188304 <sect2 xml : id =" language.oop5.visiblity-constants" >
189305 <title >定数のアクセス権</title >
@@ -192,10 +308,9 @@ $myFoo->test(); // Bar::testPrivate
192308 として定義できるようになりました。
193309 明示的に公開範囲のキーワードを明示的に宣言しない定数は、public として定義されます。
194310 </para >
195- <para >
196- <example >
197- <title >PHP 7.1.0 以降での定数の宣言</title >
198- <programlisting role =" php" >
311+ <example >
312+ <title >PHP 7.1.0 以降での定数の宣言</title >
313+ <programlisting role =" php" >
199314<![CDATA[
200315<?php
201316/**
@@ -246,9 +361,8 @@ echo MyClass2::MY_PUBLIC; // 動作します
246361$myclass2->foo2(); // Public, Protected では動作しますが、Private では動作しません
247362?>
248363]]>
249- </programlisting >
250- </example >
251- </para >
364+ </programlisting >
365+ </example >
252366 </sect2 >
253367
254368 <sect2 xml : id =" language.oop5.visibility-other-objects" >
@@ -304,7 +418,6 @@ Accessed the private method.
304418 </example >
305419 </sect2 >
306420 </sect1 >
307-
308421<!-- Keep this comment at the end of the file
309422Local variables:
310423mode: sgml
0 commit comments