<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.oop5.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ja',
  ),
  'this' => 
  array (
    0 => 'language.oop5.basic.php',
    1 => 'クラスの基礎',
    2 => 'クラスの基礎',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'クラスとオブジェクト',
  ),
  'prev' => 
  array (
    0 => 'oop5.intro.php',
    1 => 'はじめに',
  ),
  'next' => 
  array (
    0 => 'language.oop5.properties.php',
    1 => 'プロパティ',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'language/oop5/basic.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.basic" class="sect1">
 <h2 class="title">クラスの基礎</h2>

 <div class="sect2" id="language.oop5.basic.class">
  <h3 class="title">class</h3>
  <p class="para">
   各クラスの定義は、<code class="literal">class</code>キーワードで始まり、クラス名が続きます。
   そしてその後に波括弧のペアが続き、
   その中にはクラスのプロパティとメソッドの定義を記述します。
   </p>
   <p class="para">
    クラス名には、PHP の<a href="reserved.php" class="link">予約語</a>
    以外でラベルとして有効なあらゆる名前を使用することができます。
    PHP 8.4.0 以降では、アンダースコア (<code class="literal">_</code>)
    1文字のみのクラス名は非推奨となりました。
    有効なクラス名は、先頭が文字あるいはアンダースコアで始まり、
    その後に任意の数の文字/数字/アンダースコアが続くものです。
    正規表現で表すと、
    <code class="code">^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>
    のようになります。
   </p>
   <p class="para">
    クラスの中には、
    <a href="language.oop5.constants.php" class="link">定数</a> や
    <a href="language.oop5.properties.php" class="link">変数</a>
    (&quot;プロパティ&quot; といいます) そして関数 (&quot;メソッド&quot; といいます)
    を含めることができます。
   </p>
   <div class="example" id="example-1">
    <p><strong>例1 簡単なクラス定義</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">SimpleClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// プロパティの宣言<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">$var </span><span style="color: #007700">= </span><span style="color: #DD0000">'a default value'</span><span style="color: #007700">;<br /><br />    </span><span style="color: #FF8000">// メソッドの宣言<br />    </span><span style="color: #007700">public function </span><span style="color: #0000BB">displayVar</span><span style="color: #007700">() {<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">var</span><span style="color: #007700">;<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
   <p class="para">
    メソッドがオブジェクトのコンテキストからコールされる場合は、
    疑似変数 <var class="varname">$this</var> が利用可能です。
    <var class="varname">$this</var> は、呼び出し元オブジェクトの値です。
   </p>
   <div class="warning"><strong class="warning">警告</strong>
    <p class="para">
     static でないメソッドを static メソッドとしてコールすると、
     <span class="classname"><a href="class.error.php" class="classname">Error</a></span> がスローされます。
     PHP 8.0.0 より前のバージョンでは、推奨されない警告が発生し、
     <var class="varname">$this</var> が未定義になっていました。
    </p>
    <div class="example" id="language.oop5.basic.class.this">
     <p><strong>例2 <var class="varname">$this</var> 疑似変数の例</strong></p>
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">foo</span><span style="color: #007700">()<br />    {<br />        if (isset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">)) {<br />            echo </span><span style="color: #DD0000">'$this is defined ('</span><span style="color: #007700">;<br />            echo </span><span style="color: #0000BB">get_class</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">);<br />            echo </span><span style="color: #DD0000">")\n"</span><span style="color: #007700">;<br />        } else {<br />            echo </span><span style="color: #DD0000">"\$this is not defined.\n"</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">B<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">bar</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">A</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$a </span><span style="color: #007700">= new </span><span style="color: #0000BB">A</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$a</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">A</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">$b </span><span style="color: #007700">= new </span><span style="color: #0000BB">B</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bar</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">bar</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

     <div class="example-contents"><p>上の例の PHP 7 での出力は、このようになります。</p></div>
     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
$this is defined (A)

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 27
$this is not defined.

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
$this is not defined.

Deprecated: Non-static method B::bar() should not be called statically in %s  on line 32

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
$this is not defined.
</pre></div>
     </div>
     <div class="example-contents"><p>上の例の PHP 8 での出力は、このようになります。:</p></div>
     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
$this is defined (A)

Fatal error: Uncaught Error: Non-static method A::foo() cannot be called statically in %s :27
Stack trace:
#0 {main}
  thrown in %s  on line 27
</pre></div>
     </div>
    </div>
   </div>

   <div class="sect3" id="language.oop5.basic.class.readonly">
    <h4 class="title">読み取り専用クラス</h4>
    <p class="para">
     PHP 8.2.0 以降では、
     クラスに対して <span class="modifier">readonly</span> を指定することができます。
     クラスに対して <span class="modifier">readonly</span> を指定すると、
     宣言されている全ての <a href="language.oop5.properties.php#language.oop5.properties.readonly-properties" class="link">プロパティに対して <span class="modifier">readonly</span> を指定した</a> ことになり、
     かつ <a href="language.oop5.properties.php#language.oop5.properties.dynamic-properties" class="link">動的なプロパティ</a> の作成を禁止したことになります。
     さらに、<span class="classname"><a href="class.allowdynamicproperties.php" class="classname">AllowDynamicProperties</a></span>
     アトリビュートを指定しても動的なプロパティを作成できなくなります。
     動的なプロパティを作成しようとすると、コンパイル時にエラーが発生します。
    </p>
    <div class="informalexample">
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">#[</span><span style="color: #0000BB">\AllowDynamicProperties</span><span style="color: #007700">]<br />readonly class </span><span style="color: #0000BB">Foo </span><span style="color: #007700">{<br />}<br /><br /></span><span style="color: #FF8000">// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>

    <p class="para">
     型を指定していないプロパティや、
     static プロパティ に対しては <code class="literal">readonly</code> を指定できません。
     readonly クラスには、それらをいずれも指定できません:
    </p>
    <div class="informalexample">
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">readonly class </span><span style="color: #0000BB">Foo<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$bar</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #FF8000">// Fatal error: Readonly property Foo::$bar must have type<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">readonly class </span><span style="color: #0000BB">Foo<br /></span><span style="color: #007700">{<br />    public static </span><span style="color: #0000BB">int $bar</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #FF8000">// Fatal error: Readonly class Foo cannot declare static properties<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
    <p class="para">
     <span class="modifier">readonly</span> を指定したクラスは、
     子クラスでも <span class="modifier">readonly</span> を指定した場合にのみ
     <a href="language.oop5.basic.php#language.oop5.basic.extends" class="link">継承</a> できます。
    </p>
   </div>
  </div>

 <div class="sect2" id="language.oop5.basic.new">
  <h3 class="title">new</h3>
  <p class="para">
   あるクラスのインスタンスを生成するには、<code class="literal">new</code>
   キーワードを使わなければなりません。エラー時に
   <a href="language.exceptions.php" class="link">例外</a>をスローするような
   <a href="language.oop5.decon.php" class="link">コンストラクタ</a>を定義していない限り、
   オブジェクトが常に生成されます。
   クラスは、そのインスタンスを作成する前に定義すべきです
   (これが必須となる場合もあります)。
  </p>
   <p class="para">
    クラス名を含む文字列を <code class="literal">new</code> で指定すると、
    そのクラスのインスタンスを作成します。クラスが名前空間に属している場合は、
    完全修飾名を指定しなければなりません。
   </p>

   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <p class="para">
     クラスのコンストラクタに引数を渡さなかった場合、
     クラス名の後の括弧は省略しても構いません。
    </p>
   </p></blockquote>

  <div class="example" id="example-2">
   <p><strong>例3 インスタンスを作成する</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">SimpleClass </span><span style="color: #007700">{<br />}<br /><br /></span><span style="color: #0000BB">$instance </span><span style="color: #007700">= new </span><span style="color: #0000BB">SimpleClass</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$instance</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// 変数を使うこともできます<br /></span><span style="color: #0000BB">$className </span><span style="color: #007700">= </span><span style="color: #DD0000">'SimpleClass'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$instance </span><span style="color: #007700">= new </span><span style="color: #0000BB">$className</span><span style="color: #007700">(); </span><span style="color: #FF8000">// new SimpleClass()<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$instance</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="para">
   PHP 8.0.0 以降では、
   <code class="literal">new</code> を任意の式と一緒に使う機能がサポートされました。
   これによって、式が文字列を生成する場合に、
   より複雑なインスタンス化を行えるようになります。
   式は括弧で囲まなければいけません。
   </p>
   <div class="example" id="example-3">
    <p><strong>例4 任意の式を使ってインスタンスを生成する</strong></p>
    <div class="example-contents"><p>
     以下の例では、
     クラス名を生成する有効な任意の式を複数示します。
     関数呼び出し、文字列連結、そして
     <strong><code>::class</code></strong> 定数です。
    </p></div>
    <div class="example-contents">
     <div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">ClassA </span><span style="color: #007700">extends </span><span style="color: #0000BB">\stdClass </span><span style="color: #007700">{}<br />class </span><span style="color: #0000BB">ClassB </span><span style="color: #007700">extends </span><span style="color: #0000BB">\stdClass </span><span style="color: #007700">{}<br />class </span><span style="color: #0000BB">ClassC </span><span style="color: #007700">extends </span><span style="color: #0000BB">ClassB </span><span style="color: #007700">{}<br />class </span><span style="color: #0000BB">ClassD </span><span style="color: #007700">extends </span><span style="color: #0000BB">ClassA </span><span style="color: #007700">{}<br /><br />function </span><span style="color: #0000BB">getSomeClass</span><span style="color: #007700">(): </span><span style="color: #0000BB">string<br /></span><span style="color: #007700">{<br />    return </span><span style="color: #DD0000">'ClassA'</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(new (</span><span style="color: #0000BB">getSomeClass</span><span style="color: #007700">()));<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(new (</span><span style="color: #DD0000">'Class' </span><span style="color: #007700">. </span><span style="color: #DD0000">'B'</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(new (</span><span style="color: #DD0000">'Class' </span><span style="color: #007700">. </span><span style="color: #DD0000">'C'</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(new (</span><span style="color: #0000BB">ClassD</span><span style="color: #007700">::class));<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    <div class="example-contents"><p>上の例の PHP 8 での出力は、このようになります。:</p></div>
    <div class="example-contents screen">
     <div class="annotation-interactive cdata"><pre>
object(ClassA)#1 (0) {
}
object(ClassB)#1 (0) {
}
object(ClassC)#1 (0) {
}
object(ClassD)#1 (0) {
}

</pre></div>
    </div>
   </div>
   <p class="para">
    クラスのコンテキストにおいては、
    <code class="literal">new self</code> や <code class="literal">new parent</code>
    のようにして新しいオブジェクトを作成することができます。
   </p>
  <p class="para">
   作成済みのクラスのインスタンスを新たな変数に代入する場合、新しい変数は、
   代入されたオブジェクトと同じインスタンスにアクセスします。
   この動作は、インスタンスを関数に渡す場合も同様です。
   作成済みのオブジェクトのコピーは、その
   <a href="language.oop5.cloning.php" class="link">クローンを作成</a>
   することにより作成可能です。
  </p>
  <div class="example" id="example-4">
   <p><strong>例5 オブジェクトの代入</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">SimpleClass </span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $var</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$instance </span><span style="color: #007700">= new </span><span style="color: #0000BB">SimpleClass</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">$assigned   </span><span style="color: #007700">=  </span><span style="color: #0000BB">$instance</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$reference  </span><span style="color: #007700">=&amp; </span><span style="color: #0000BB">$instance</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$instance</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">var </span><span style="color: #007700">= </span><span style="color: #DD0000">'$assigned will have this value'</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$instance </span><span style="color: #007700">= </span><span style="color: #0000BB">null</span><span style="color: #007700">; </span><span style="color: #FF8000">// $instance と $reference は null になります<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$instance</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$reference</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$assigned</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
NULL
NULL
object(SimpleClass)#1 (1) {
   [&quot;var&quot;]=&gt;
     string(30) &quot;$assigned will have this value&quot;
}
</pre></div>
    </div>
   </div>
   <p class="para">
    複数のやり方で、オブジェクトのインスタンスを作ることが出来ます:
   </p>
   <div class="example" id="example-5">
    <p><strong>例6 新しいオブジェクトの作成</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Test<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">getNew</span><span style="color: #007700">()<br />    {<br />        return new static();<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">Child </span><span style="color: #007700">extends </span><span style="color: #0000BB">Test </span><span style="color: #007700">{}<br /><br /></span><span style="color: #0000BB">$obj1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test</span><span style="color: #007700">(); </span><span style="color: #FF8000">// By the class name<br /></span><span style="color: #0000BB">$obj2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">$obj1</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Through the variable containing an object<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$obj1 </span><span style="color: #007700">!== </span><span style="color: #0000BB">$obj2</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$obj3 </span><span style="color: #007700">= </span><span style="color: #0000BB">Test</span><span style="color: #007700">::</span><span style="color: #0000BB">getNew</span><span style="color: #007700">(); </span><span style="color: #FF8000">// By the class method<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$obj3 </span><span style="color: #007700">instanceof </span><span style="color: #0000BB">Test</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$obj4 </span><span style="color: #007700">= </span><span style="color: #0000BB">Child</span><span style="color: #007700">::</span><span style="color: #0000BB">getNew</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Through a child class method<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$obj4 </span><span style="color: #007700">instanceof </span><span style="color: #0000BB">Child</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
    <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
bool(true)
bool(true)
bool(true)
</pre></div>
    </div>
   </div>

   <p class="para">
    新しく作成したオブジェクトのメンバーに、作成したその式の中でもアクセスすることができます。
   </p>
   <div class="example" id="example-6">
    <p><strong>例7 新しく作成したオブジェクトのメンバーへのアクセス</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">echo (new </span><span style="color: #0000BB">DateTime</span><span style="color: #007700">())-&gt;</span><span style="color: #0000BB">format</span><span style="color: #007700">(</span><span style="color: #DD0000">'Y'</span><span style="color: #007700">), </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// PHP 8.4.0 以降、囲む括弧は省略可能です。<br /></span><span style="color: #007700">echo new </span><span style="color: #0000BB">DateTime</span><span style="color: #007700">()-&gt;</span><span style="color: #0000BB">format</span><span style="color: #007700">(</span><span style="color: #DD0000">'Y'</span><span style="color: #007700">), </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    <div class="example-contents"><p>上の例の出力は、
たとえば以下のようになります。</p></div>
    <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
2025
2025
</pre></div>
    </div>
   </div>

   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <span class="simpara">
     PHP 7.1 より前のバージョンでは、コンストラクタが定義されない場合、それへの引数が評価されていませんでした。
    </span>
   </p></blockquote>
  </div>
  
  <div class="sect2" id="language.oop5.basic.properties-methods">
   <h3 class="title">プロパティとメソッド</h3>
   <p class="para">
    クラスのプロパティとメソッドは、それぞれ別の &quot;名前空間&quot; に存在するので、
    同じ名前のプロパティとメソッドを共存させることもできます。
    プロパティを参照する場合もメソッドを参照する場合も書きかたは同じです。
    それがプロパティへのアクセスなのかメソッドの呼び出しなのかは、そのコンテキストによって決まります。
    つまり、変数にアクセスしようとしているのか関数を呼び出そうとしているのかの違いです。
   </p>
   <div class="example" id="example-7">
    <p><strong>例8 プロパティへのアクセスとメソッドの呼び出し</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Foo<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$bar </span><span style="color: #007700">= </span><span style="color: #DD0000">'property'</span><span style="color: #007700">;<br />    <br />    public function </span><span style="color: #0000BB">bar</span><span style="color: #007700">() {<br />        return </span><span style="color: #DD0000">'method'</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bar</span><span style="color: #007700">, </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">, </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bar</span><span style="color: #007700">(), </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;</span></span></code></div>
    </div>

    <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
    <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
property
method
</pre></div>
    </div>
   </div>
   <p class="para">
    これはつまり、プロパティに <a href="functions.anonymous.php" class="link">無名関数</a>
    を代入した場合に、その関数は直接呼び出せないということです。
    その場合は、たとえば事前にプロパティを変数に代入しておく必要があります。
    括弧で囲むと、プロパティを直接呼び出すこともできます。
   </p>
   <div class="example" id="example-8">
    <p><strong>例9 プロパティに格納した無名関数の呼び出し</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Foo<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$bar</span><span style="color: #007700">;<br />    <br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">() {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bar </span><span style="color: #007700">= function() {<br />            return </span><span style="color: #0000BB">42</span><span style="color: #007700">;<br />        };<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">();<br /><br />echo (</span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bar</span><span style="color: #007700">)(), </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;</span></span></code></div>
    </div>

    <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
    <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
42
</pre></div>
    </div>
   </div>
  </div>

 <div class="sect2" id="language.oop5.basic.extends">
   
   
  <h3 class="title">extends</h3>
  <p class="para">
   クラスは、宣言部に <code class="literal">extends</code> キーワードを含めることで、
   他のクラスの定数や、メソッド、
   およびプロパティを継承することができます。多重継承を行うことはできず、クラスが継承できるベース
   クラスは一つだけです。
  </p>
  <p class="para">
    継承された定数やメソッド、プロパティをオーバーライド(上書き)するには、
    親クラスで定義されているのと同じ名前でそれを再宣言します。
    しかし、親クラスでそのメソッドや定数が
    <a href="language.oop5.final.php" class="link">final</a>
    として定義されている場合はオーバーライドできません。
    オーバーライドされた元のメソッドやstaticプロパティにアクセスするには、
    <a href="language.oop5.paamayim-nekudotayim.php" class="link">parent::</a>
    で参照します。
  </p>
   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <span class="simpara">
     PHP 8.1.0 以降では、定数も final として宣言できます。
    </span>
   </p></blockquote>
  <div class="example" id="example-9">
   <p><strong>例10 簡単なクラスの継承</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">SimpleClass<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">displayVar</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #DD0000">"Parent class\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">ExtendClass </span><span style="color: #007700">extends </span><span style="color: #0000BB">SimpleClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// 親クラスのメソッドを再定義<br />    </span><span style="color: #007700">function </span><span style="color: #0000BB">displayVar</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #DD0000">"Extending class\n"</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">displayVar</span><span style="color: #007700">();<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$extended </span><span style="color: #007700">= new </span><span style="color: #0000BB">ExtendClass</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$extended</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">displayVar</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Extending class
Parent Class
</pre></div>
   </div>
  </div>

   <div class="sect3" id="language.oop.lsp">
    <h4 class="title">シグネチャの互換性に関するルール</h4>
    <p class="para">
     メソッドをオーバーライドするときは、
     子クラスのシグネチャが親クラスのそれと互換性がなければいけません。
     互換性が壊れた場合、致命的なエラーが発生します。
     PHP 8.0.0 より前のバージョンでは、
     互換性が壊れた場合に、<strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> レベルの警告が発生していました。
     <a href="language.oop5.variance.php" class="link">共変性と反変性</a>
     の規則を守っている場合は、シグネチャに互換性があります。
     必須のパラメータをオプションにした場合も、互換性があります。
     新しいオプションのパラメータを追加しただけで、アクセス権を厳しくせず、
     緩めただけの場合も互換性があります。
     これは、リスコフの置換原則(Liskov Substitution Principle)、
     略して LSP として知られています。
     但し、<a href="language.oop5.decon.php#language.oop5.decon.constructor" class="link">コンストラクタ</a>
     と <code class="literal">private</code> メソッドについては、
     この規則の例外で、
     オーバライドしたシグネチャにミスマッチがあっても致命的なエラーにはなりません。
    </p>
    <div class="example" id="example-10">
     <p><strong>例11 互換性がある子クラスのメソッド</strong></p>
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Base<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a</span><span style="color: #007700">) {<br />        echo </span><span style="color: #DD0000">"Valid\n"</span><span style="color: #007700">;<br />    }<br />}<br />class </span><span style="color: #0000BB">Extend1 </span><span style="color: #007700">extends </span><span style="color: #0000BB">Base<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">);<br />    }<br />}<br />class </span><span style="color: #0000BB">Extend2 </span><span style="color: #007700">extends </span><span style="color: #0000BB">Base<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">);<br />    }<br />}<br /></span><span style="color: #0000BB">$extended1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Extend1</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$extended1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$extended2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Extend2</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$extended2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">);</span></span></code></div>
     </div>

     <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Valid
Valid
</pre></div>
     </div>
    </div>

    <p class="para">
     次の例は、パラメータを削除した子クラスのメソッドや、
     オプションのパラメータを必須にしたりすることが、親クラスのメソッドと互換性がなくなることを示しています。
    </p>
    <div class="example" id="example-11">
     <p><strong>例12 子クラスのメソッドでパラメータを削除すると致命的なエラーになる</strong></p>
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Base<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">) {<br />        echo </span><span style="color: #DD0000">"Valid\n"</span><span style="color: #007700">;<br />    }<br />}<br />class </span><span style="color: #0000BB">Extend </span><span style="color: #007700">extends </span><span style="color: #0000BB">Base<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">foo</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />    }<br />}</span></span></code></div>
     </div>

     <div class="example-contents"><p>上の例の PHP 8 での出力は、たとえば以下のようになります。:</p></div>
     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Fatal error: Declaration of Extend::foo() must be compatible with Base::foo(int $a = 5) in /in/evtlq on line 13
</pre></div>
     </div>
    </div>
    <div class="example" id="example-12">
     <p><strong>例13 子クラスのメソッドで、オプションのパラメータを必須にすると致命的なエラーになる</strong></p>
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Base<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">) {<br />        echo </span><span style="color: #DD0000">"Valid\n"</span><span style="color: #007700">;<br />    }<br />}<br />class </span><span style="color: #0000BB">Extend </span><span style="color: #007700">extends </span><span style="color: #0000BB">Base<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">int $a</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">);<br />    }<br />}</span></span></code></div>
     </div>

     <div class="example-contents"><p>上の例の PHP 8 での出力は、たとえば以下のようになります。:</p></div>
     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Fatal error: Declaration of Extend::foo(int $a) must be compatible with Base::foo(int $a = 5) in /in/qJXVC on line 13
</pre></div>
     </div>
    </div>

    <div class="warning"><strong class="warning">警告</strong>
     <p class="para">
      メソッドのパラメータの名前を子クラスで変更しても、
      シグネチャ上は非互換になりません。
      しかし、こうしてしまうと
      <a href="functions.arguments.php#functions.named-arguments" class="link">名前付き引数</a>
      を使った時に実行時エラーになるので、おすすめできません。
     </p>
     <div class="example" id="example-13">
      <p><strong>例14 子クラスでパラメータの名前を変更し、かつ名前付き引数を使うとエラーになる</strong></p>
      <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">A </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">test</span><span style="color: #007700">(</span><span style="color: #0000BB">$foo</span><span style="color: #007700">, </span><span style="color: #0000BB">$bar</span><span style="color: #007700">) {}<br />}<br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">test</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">) {}<br />}<br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">B</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// A::test() の規約に従って引数を渡す<br /></span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">test</span><span style="color: #007700">(</span><span style="color: #0000BB">foo</span><span style="color: #007700">: </span><span style="color: #DD0000">"foo"</span><span style="color: #007700">, </span><span style="color: #0000BB">bar</span><span style="color: #007700">: </span><span style="color: #DD0000">"bar"</span><span style="color: #007700">); </span><span style="color: #FF8000">// エラー発生!</span></span></code></div>
      </div>

      <div class="example-contents"><p>上の例の出力は、
たとえば以下のようになります。</p></div>
      <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Fatal error: Uncaught Error: Unknown named parameter $foo in /in/XaaeN:14
Stack trace:
#0 {main}
  thrown in /in/XaaeN on line 14
</pre></div>
      </div>
     </div>
    </div>
   </div>
 </div>

  <div class="sect2" id="language.oop5.basic.class.class">
   <h3 class="title">::class</h3>

   <p class="para">
    <code class="literal">class</code> キーワードでもクラス名の解決を行うことが出来ます。
    クラスの名前が <code class="literal">ClassName</code> になっているクラスの完全修飾名を取得するには、
    <code class="literal">ClassName::class</code> を使います。
    これは、<a href="language.namespaces.php" class="link">名前空間</a>付きのクラスに使うと特に便利です。
   </p>
   <p class="para">
    <div class="example" id="language.oop5.basic.class.class.name">
     <p><strong>例15 クラス名の解決</strong></p>
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">namespace </span><span style="color: #0000BB">NS </span><span style="color: #007700">{<br />    class </span><span style="color: #0000BB">ClassName </span><span style="color: #007700">{<br />    }<br />    <br />    echo </span><span style="color: #0000BB">ClassName</span><span style="color: #007700">::class;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

     <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
NS\ClassName
</pre></div>
     </div>
    </div>
   </p>
   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <p class="para">
     <code class="literal">::class</code> によるクラス名の解決は、コンパイル時の変換です。
     つまり、クラス名を作るタイミングでは、まだオートロードが行われていないということです。
     結果的に、クラスがまだ存在しない時点でクラス名が展開されることになります。
     この場合にはエラーは発生しません。
    </p>
    <div class="example" id="language.oop5.basic.class.class.fail">
     <p><strong>例16 クラス名が存在しない場合の名前解決</strong></p>
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">print </span><span style="color: #0000BB">Does\Not\Exist</span><span style="color: #007700">::class;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

     <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
     <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Does\Not\Exist
</pre></div>
     </div>
    </div>
   </p></blockquote>
   <p class="para">
    PHP 8.0.0 以降では、
    <code class="literal">::class</code> はオブジェクトに対しても使えるようになりました。
    この名前解決はコンパイル時ではなく、実行時に行われます。
    この場合、<span class="function"><a href="function.get-class.php" class="function">get_class()</a></span> をオブジェクトに対して使った時と同じ動きをします。
   </p>
   <div class="example" id="language.oop5.basic.class.class.object">
    <p><strong>例17 オブジェクトの名前解決</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">namespace </span><span style="color: #0000BB">NS </span><span style="color: #007700">{<br />    class </span><span style="color: #0000BB">ClassName </span><span style="color: #007700">{<br />    }<br /><br />    </span><span style="color: #0000BB">$c </span><span style="color: #007700">= new </span><span style="color: #0000BB">ClassName</span><span style="color: #007700">();<br />    print </span><span style="color: #0000BB">$c</span><span style="color: #007700">::class;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
    <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
NS\ClassName
</pre></div>
    </div>
   </div>
  </div>
 <div class="sect2" id="language.oop5.basic.nullsafe">
  <h3 class="title">nullsafe メソッドとプロパティ</h3>
  <p class="para">
   PHP 8.0.0 以降では、プロパティやメソッドは
   &quot;nullsafe&quot; 演算子 <code class="literal">?-&gt;</code> を使ってアクセスすることもできます。
   nullsafe 演算子は既に述べたメソッドやプロパティと同じように振る舞いますが、
   オブジェクトが <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> と評価された場合に、例外はスローされず、
   <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> が返される点だけが異なります。
   オブジェクトの評価がチェインの一部だった場合は、
   残りのチェインはスキップされます。
  </p>
  <p class="para">
   この演算子の働きは、
   オブジェクトにアクセスするたびに <span class="function"><a href="function.is-null.php" class="function">is_null()</a></span> でラップするコードに似ています。
   しかし、よりコンパクトです。
  </p>
  <p class="para">
   <div class="example" id="example-14">
    <p><strong>例18 nullsafe 演算子</strong></p>
    <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #FF8000">// PHP 8.0.0 以降は、このように書けます:<br /></span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">$repository</span><span style="color: #007700">?-&gt;</span><span style="color: #0000BB">getUser</span><span style="color: #007700">(</span><span style="color: #0000BB">5</span><span style="color: #007700">)?-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// これは、以下のコードチェックと同等です:<br /></span><span style="color: #007700">if (</span><span style="color: #0000BB">is_null</span><span style="color: #007700">(</span><span style="color: #0000BB">$repository</span><span style="color: #007700">)) {<br />    </span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br />} else {<br />    </span><span style="color: #0000BB">$user </span><span style="color: #007700">= </span><span style="color: #0000BB">$repository</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getUser</span><span style="color: #007700">(</span><span style="color: #0000BB">5</span><span style="color: #007700">);<br />    if (</span><span style="color: #0000BB">is_null</span><span style="color: #007700">(</span><span style="color: #0000BB">$user</span><span style="color: #007700">)) {<br />        </span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br />    } else {<br />        </span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">$user</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">;<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <p class="para">
    nullsafe 演算子は、プロパティやメソッドが値を返す際、
    null が正しく、期待されうる値とみなせる場合に一番よく使います。
    エラーを示すためなら、例外をスローするほうが好ましいです。
   </p>
  </p></blockquote>
 </div>
</div><?php manual_footer($setup); ?>