svn: /phpdoc/ja/trunk/language/oop5/ decon.xml

[email protected] (Yoshinari Takaoka)
Newsgroups php.doc.ja
Message-ID <[email protected]>
mumumu                                   Sun, 22 Nov 2020 00:52:50 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=351482

Log:
[status: working] Update constructor documentation to include constructor promotion.

Changed paths:
    U   phpdoc/ja/trunk/language/oop5/decon.xml
svn-diffs-351482.txt (text/x-diff, 10.5 KB)
Modified: phpdoc/ja/trunk/language/oop5/decon.xml
===================================================================
--- phpdoc/ja/trunk/language/oop5/decon.xml	2020-11-22 00:31:22 UTC (rev 351481)
+++ phpdoc/ja/trunk/language/oop5/decon.xml	2020-11-22 00:52:50 UTC (rev 351482)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- $Revision$ -->
-<!-- EN-Revision: 351129 Maintainer: hirokawa Status: ready -->
+<!-- EN-Revision: 351474 Maintainer: hirokawa Status: working -->
 <!-- CREDITS: shimooka,mumumu -->

 <sect1 xml:id="language.oop5.decon" xmlns="http://docbook.org/ns/docbook">
@@ -13,7 +13,7 @@
     <methodparam rep="repeat"><type>mixed</type><parameter>values</parameter><initializer>""</initializer></methodparam>
    </methodsynopsis>
   <para>
-   PHP 5 では、開発者がクラスのコンストラクタメソッドを宣言することが
+   PHP では、開発者がクラスのコンストラクタメソッドを宣言することが
    できます。コンストラクタメソッドを有するクラスは、新たにオブジェクトが
    生成される度にこのメソッドをコールします。これにより、
    そのオブジェクトを使用する前に必要な初期化を行うことができます。
@@ -31,7 +31,7 @@
    </simpara>
   </note>
   <example>
-   <title>新しい統一されたコンストラクタを使用する</title>
+   <title>継承とコンストラクタ</title>
    <programlisting role="php">
 <![CDATA[
 <?php
@@ -65,23 +65,6 @@
 ]]>
    </programlisting>
   </example>
-  <para>
-   PHP 3 や PHP 4 との下位互換性を維持するため、もし PHP がクラスの
-   <link linkend="object.construct">__construct()</link> 関数を見つけられない場合は、
-   古い形式のコンストラクタ (つまりクラス名と同じ名前の関数)を捜します。
-   事実上、互換性の問題が発生する可能性があるのは、
-   そのクラスが <link linkend="object.construct">__construct()</link> という名前のメソッドを
-   異なる用途で用いてる場合だけです。
-  </para>
-   <!-- Not using an entity because I want specific wording here, since we're
-   not deprecating constructors in general. -->
-   <warning>
-    <simpara>
-     古い形式のコンストラクタは PHP 7.0 で <emphasis>非推奨</emphasis> となりました。
-     将来のバージョンで削除されるでしょう。新しいコードでは常に
-     <link linkend="object.construct">__construct()</link> を使うべきです。
-    </simpara>
-   </warning>
    <para>
     他のメソッドと異なり、親の <link linkend="object.construct">__construct()</link>
     と異なるパラメータで <link linkend="object.construct">__construct()</link>
@@ -89,28 +72,177 @@
     <constant>E_STRICT</constant> エラーメッセージを出しません。
    </para>
    <para>
-    PHP 5.3.3 以降、名前空間つきのクラス名の最後の部分と同じ名前のメソッドは
-    コンストラクタとみなされなくなりました。
-    名前空間を使っていないクラスは今までと変わりません。
+    コンストラクタは、対応するオブジェクトを初期化する間に呼び出されるメソッドです。
+    よって、任意の数の引数を取ることが出来ます。
+    この引数は必須にすることもできますし、型宣言もできますし、デフォルト値を取ったりすることもできます。
+    コンストラクタの引数は、クラス名の後の括弧に、引数を置くことで指定することが出来ます。
    </para>
    <example>
-    <title>名前空間つきのクラスのコンストラクタ</title>
+    <title>コンストラクタを引数と一緒に使う</title>
     <programlisting role="php">
 <![CDATA[
 <?php
-namespace Foo;
-class Bar {
-    public function Bar() {
-        // PHP 5.3.0-5.3.2 までは、これはコンストラクタとみなされました
-        // PHP 5.3.3 以降は、これはコンストラクタにはなりません
+class Point {
+    protected int $x;
+    protected int $y;
+
+    public function __construct(int $x, int $y = 0) {
+        $this->x = $x;
+        $this->y = $y;
     }
 }
+
+// 引数を両方渡す
+$p1 = new Point(4, 5);
+// 必須の引数のみを渡す。$y はデフォルト値0になります。
+$p2 = new Point(4);
+// 名前付き引数(PHP 8.0 以降):
+$p3 = new Point(y: 5, x: 4);
 ?>
 ]]>
     </programlisting>
    </example>
- </sect2>
+   <!-- to be translated -->
+   <para>
+    If a class has no constructor, or the constructor has no required arguments, the parentheses
+    may be omitted.
+   </para>
+   <sect3>
+    <title>Old-style constructors</title>
+    <para>
+     Prior to PHP 8.0.0, classes in the global namespace will interpret a method named
+     the same as the class as an old-style constructor.  That syntax is deprecated,
+     and will result in an <constant>E_DEPRECATED</constant> error but still call that function as a constructor.
+     If both <link linkend="object.construct">__construct()</link> and a same-name method are
+     defined, <link linkend="object.construct">__construct()</link> will be called.
+    </para>
+    <para>
+     In namespaced classes, or any class as of PHP 8.0.0, a method named
+     the same as the class never has any special meaning.
+    </para>
+    <para>Always use <link linkend="object.construct">__construct()</link> in new code.
+    </para>
+   </sect3>
+   <sect3 xml:id="language.oop5.decon.constructor.promotion">
+    <title>Constructor Promotion</title>
+    <para>
+     As of PHP 8.0.0, constructor parameters may also be promoted to correspond to an
+     object property.  It is very common for constructor parameters to be assigned to
+     a property in the constructor but otherwise not operated upon.  Constructor promotion
+     provides a short-hand for that use case.  The example above could be rewritten as the following.
+    </para>
+    <example>
+     <title>Using constructor property promotion</title>
+     <programlisting role="php">
+<![CDATA[
+<?php
+class Point {
+    public function __construct(protected int $x, protected int $y = 0) {
+    }
+}
+]]>
+     </programlisting>
+    </example>
+    <para>
+     When a constructor argument includes a visibility modifier, PHP will interpret it as
+     both an object property and a constructor argument, and assign the argument value to
+     the property.  The constructor body may then be empty or may contain other statements.
+     Any additional statements will be executed after the argument values have been assigned
+     to the corresponding properties.
+    </para>
+    <para>
+     Not all arguments need to be promoted. It is possible to mix and match promoted and not-promoted
+     arguments, in any order.  Promoted arguments have no impact on code calling the constructor.
+    </para>
+    <note>
+     <para>
+      Object properties may not be typed <type>callable</type> due to engine ambiguity that would
+      introduce. Promoted arguments, therefore, may not be typed <type>callable</type> either. Any
+      other <link linkend="language.types.declarations">type declaration</link> is permitted, however.
+     </para>
+    </note>
+    <note>
+     <para>
+      <!-- This should be linked once attributes are documented. -->
+      Attributes placed on a promoted constructor argument will be replicated to both the property
+      and argument.
+     </para>
+    </note>
+   </sect3>
+   <sect3 xml:id="language.oop5.decon.constructor.static">
+    <title>Static creation methods</title>
+    <para>
+     PHP only supports a single constructor per class.  In some cases, however, it may be
+     desirable to allow an object to be constructed in different ways with different inputs.
+     The recommended way to do so is by using static methods as constructor wrappers.
+    </para>
+    <example>
+     <title>Using static creation methods</title>
+     <programlisting role="php">
+<![CDATA[
+<?php
+class Product {

+    private ?int $id;
+    private ?string $name;
+
+    private function __construct(?int $id = null, ?string $name = null) {
+        $this->id = $id;
+        $this->name = $name;
+    }
+
+    public static function fromBasicData(int $id, string $name): static {
+        $new = new static($id, $name);
+        return $new;
+    }
+
+    public static function fromJson(string $json): static {
+        $data = json_decode($json);
+        return new static($data['id'], $data['name']);
+    }
+
+    public static function fromXml(string $xml): static {
+        // Put your own logic here.
+        $data = convert_xml_to_array($xml);
+        $new = new static();
+        $new->id = $data['id'];
+        $new->name = $data['name'];
+        return $new;
+    }
+}
+
+$p1 = Product::fromBasicData(5, 'Widget');
+$p2 = Product::fromJson($some_json_string);
+$p3 = Product::fromXml($some_xml_string);
+]]>
+     </programlisting>
+    </example>
+    <para>
+     The constructor may be made private or protected to prevent it from being called externally.
+     If so, only a static method will be able to instantiate the class.  Because they are in the
+     same class definition they have access to private methods, even if not of the same object
+     instance.  The private constructor is optional and may or may not make sense depending on
+     the use case..
+    </para>
+    <para>
+     The three public static methods then demonstrate different ways of instantiating the object.
+    </para>
+    <simplelist>
+     <member><code>fromBasicData()</code> takes the exact parameters that are needed, then creates the
+      object by calling the constructor and returning the result.</member>
+     <member><code>fromJson()</code> accepts a JSON string and does some pre-processing on it itself
+     to convert it into the format desired by the constructor. It then returns the new object.</member>
+     <member><code>fromXml()</code> accepts an XML string, preprocesses it, and then creates a bare
+     object.  The constructor is still called, but as all of the parameters are optional the method
+     skips them.  It then assigns values to the object properties directly before returning the result.</member>
+    </simplelist>
+    <para>
+     In all three cases, the <code>static</code> keyword is translated into the name of the class the code is in.
+     In this case, <code>Product</code>.
+    </para>
+   </sect3>
+  </sect2>
+
  <sect2 xml:id="language.oop5.decon.destructor">
   <title>デストラクタ</title>
    <methodsynopsis xml:id="object.destruct">
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.