<?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 => 'zh',
  ),
  'this' => 
  array (
    0 => 'language.oop5.visibility.php',
    1 => '访问控制（可见性）',
    2 => '访问控制（可见性）',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => '类与对象',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.decon.php',
    1 => '构造函数和析构函数',
  ),
  'next' => 
  array (
    0 => 'language.oop5.inheritance.php',
    1 => '对象继承',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'zh',
    'path' => 'language/oop5/visibility.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.visibility" class="sect1">
  <h2 class="title">访问控制（可见性）</h2>
  <p class="para">
   对属性或方法的访问控制（PHP 7.1.0 以后支持常量），是通过在前面添加关键字
   <code class="literal">public</code>（公有），<code class="literal">protected</code>（受保护）或
   <code class="literal">private</code>（私有）来实现的。被定义为公有的类成员可以在任何地方被访问。
   被定义为受保护的类成员则可以被其自身以及其子类和父类访问。被定义为私有的类成员则只能被其定义所在的类访问。
  </p>

  <div class="sect2" id="language.oop5.visiblity-members">
   <h3 class="title">属性的访问控制</h3>
   <p class="para">
    类属性可以定义为public， private 或者 protected。在没有任何访问控制关键字的情况下，属性声明为 public。
   </p>
   <div class="example" id="example-1">
    <p><strong>示例 #1 属性声明</strong></p>
    <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">/**<br /> * Define MyClass<br /> */<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$public </span><span style="color: #007700">= </span><span style="color: #DD0000">'Public'</span><span style="color: #007700">;<br />    protected </span><span style="color: #0000BB">$protected </span><span style="color: #007700">= </span><span style="color: #DD0000">'Protected'</span><span style="color: #007700">;<br />    private </span><span style="color: #0000BB">$private </span><span style="color: #007700">= </span><span style="color: #DD0000">'Private'</span><span style="color: #007700">;<br /><br />    function </span><span style="color: #0000BB">printHello</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">public</span><span style="color: #007700">;<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">protected</span><span style="color: #007700">;<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">private</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">MyClass</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">public</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行能被正常执行<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">protected</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行会产生一个致命错误<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">private</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行也会产生一个致命错误<br /></span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printHello</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 输出 Public、Protected 和 Private<br /><br /><br />/**<br /> * Define MyClass2<br /> */<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass2 </span><span style="color: #007700">extends </span><span style="color: #0000BB">MyClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// 可以对 public 和 protected 进行重定义，但 private 而不能<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">$public </span><span style="color: #007700">= </span><span style="color: #DD0000">'Public2'</span><span style="color: #007700">;<br />    protected </span><span style="color: #0000BB">$protected </span><span style="color: #007700">= </span><span style="color: #DD0000">'Protected2'</span><span style="color: #007700">;<br /><br />    function </span><span style="color: #0000BB">printHello</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">public</span><span style="color: #007700">;<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">protected</span><span style="color: #007700">;<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">private</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$obj2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyClass2</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$obj2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">public</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行能被正常执行<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">$obj2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">protected</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行会产生一个致命错误<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">$obj2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">private</span><span style="color: #007700">; </span><span style="color: #FF8000">// 未定义 private<br /></span><span style="color: #0000BB">$obj2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printHello</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 输出 Public2、Protected2 和 Undefined<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
   <div class="sect3" id="language.oop5.visibility-members-aviz">
    <h4 class="title">不对称属性可见性</h4>
    <p class="simpara">
     从 PHP 8.4 开始，对象属性也可以设置不对称的可见性，读取（<code class="literal">get</code>）
     和写入（<code class="literal">set</code>）可以有不同的范围。
     具体来说，可以单独指定<code class="literal">set</code>可见性，只要它不比默认可见性更宽。
    </p>
    <div class="example" id="example-2">
     <p><strong>示例 #2 不对称属性可见性</strong></p>
     <div class="example-contents">
<div class="annotation-non-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">Book<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(<br />        public private(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">string $title</span><span style="color: #007700">,<br />        public protected(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">string $author</span><span style="color: #007700">,<br />        protected private(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">int $pubYear</span><span style="color: #007700">,<br />    ) {}<br />}<br /><br />class </span><span style="color: #0000BB">SpecialBook </span><span style="color: #007700">extends </span><span style="color: #0000BB">Book<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">update</span><span style="color: #007700">(</span><span style="color: #0000BB">string $author</span><span style="color: #007700">, </span><span style="color: #0000BB">int $year</span><span style="color: #007700">): </span><span style="color: #0000BB">void<br />    </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">author </span><span style="color: #007700">= </span><span style="color: #0000BB">$author</span><span style="color: #007700">; </span><span style="color: #FF8000">// OK<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">pubYear </span><span style="color: #007700">= </span><span style="color: #0000BB">$year</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal Error<br />    </span><span style="color: #007700">}<br />}<br /><br /></span><span style="color: #0000BB">$b </span><span style="color: #007700">= new </span><span style="color: #0000BB">Book</span><span style="color: #007700">(</span><span style="color: #DD0000">'How to PHP'</span><span style="color: #007700">, </span><span style="color: #DD0000">'Peter H. Peterson'</span><span style="color: #007700">, </span><span style="color: #0000BB">2024</span><span style="color: #007700">);<br /><br />echo </span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">title</span><span style="color: #007700">; </span><span style="color: #FF8000">// Works<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">author</span><span style="color: #007700">; </span><span style="color: #FF8000">// Works<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">pubYear</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal Error<br /><br /></span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">title </span><span style="color: #007700">= </span><span style="color: #DD0000">'How not to PHP'</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal Error<br /></span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">author </span><span style="color: #007700">= </span><span style="color: #DD0000">'Pedro H. Peterson'</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal Error<br /></span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">pubYear </span><span style="color: #007700">= </span><span style="color: #0000BB">2023</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal Error<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

   </div>
    <p class="simpara">
     从 PHP 8.5 开始，<code class="literal">set</code> 可见性也可以应用于类的静态属性。
    </p>
    <div class="example" id="example-3">
     <p><strong>示例 #3 不对称静态属性可见性</strong></p>
     <div class="example-contents">
<div class="annotation-non-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">Manager<br /></span><span style="color: #007700">{<br />    public private(</span><span style="color: #0000BB">set</span><span style="color: #007700">) static </span><span style="color: #0000BB">int $calls </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">doAThing</span><span style="color: #007700">(): </span><span style="color: #0000BB">string<br />    </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">$calls</span><span style="color: #007700">++;<br />        </span><span style="color: #FF8000">// Do other stuff.<br />        </span><span style="color: #007700">return </span><span style="color: #DD0000">"some string"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$m </span><span style="color: #007700">= new </span><span style="color: #0000BB">Manager</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">$m</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">doAThing</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Works<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">Manager</span><span style="color: #007700">::</span><span style="color: #0000BB">$calls</span><span style="color: #007700">; </span><span style="color: #FF8000">// Works<br /></span><span style="color: #0000BB">Manager</span><span style="color: #007700">::</span><span style="color: #0000BB">$calls </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal error<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>
1
Fatal error: Uncaught Error: Cannot modify private(set) property Manager::$calls from global scope in /some/file.php
</pre></div>
     </div>
    </div>
   <p class="para">关于不对称可见性有一些注意事项：</p>
    <ul class="itemizedlist">
     <li class="listitem">
      <span class="simpara">
       只有声明了类型的属性才能有单独的<code class="literal">set</code>可见性。
      </span>
     </li>
     <li class="listitem">
      <span class="simpara">
       <code class="literal">set</code> 可见性必须和 <code class="literal">get</code> 可见性相同或更严格。
       也就是说，<code class="code">public protected(set)</code> 和 <code class="code">protected protected(set)</code>
       是允许的，但是 <code class="code">protected public(set)</code> 会导致语法错误。
      </span>
     </li>
     <li class="listitem">
      <span class="simpara">
       如果一个属性是 <code class="literal">public</code>，那么主要可见性可能被省略。
       也就是说，<code class="code">public private(set)</code> 和 <code class="code">private(set)</code>
       会有相同的结果。
      </span>
     </li>
     <li class="listitem">
      <span class="simpara">
       一个属性的 <code class="literal">private(set)</code> 可见性会自动变为 <code class="literal">final</code>，
       并且不能在子类中重新声明。
      </span>
     </li>
     <li class="listitem">
      <span class="simpara">
       读取属性的引用遵循 <code class="literal">set</code> 可见性，而不是 <code class="literal">get</code>。
       这是因为引用可能用于修改属性值。
      </span>
     </li>
     <li class="listitem">
      <span class="simpara">
       同样，试图写入数组属性会涉及到内部的 <code class="literal">get</code> 和 <code class="literal">set</code> 操作，
       因此会遵循 <code class="literal">set</code> 可见性，因为这总是更严格的。
      </span>
     </li>
    </ul>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <span class="simpara">
      设置访问控制时，声明中不允许有空格。<code class="literal">private(set)</code>
      是正确的。<code class="literal">private( set )</code> 是不正确的，将导致解析错误。
     </span>
    </p></blockquote>
    <p class="simpara">
     当一个类继承另一个类时，子类可以重新定义任何不是 <code class="literal">final</code> 的属性。
     这样做时，可以扩大主要可见性或 <code class="literal">set</code> 可见性，只要新的可见性和父类相同或更宽。
     但是要注意，如果一个 <code class="literal">private</code> 属性被重写，它实际上并没有改变父类的属性，
     而是创建了一个具有不同内部名称的新属性。
    </p>
    <div class="example" id="example-4">
     <p><strong>示例 #4 不对称属性继承</strong></p>
     <div class="example-contents">
<div class="annotation-non-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">Book<br /></span><span style="color: #007700">{<br />    protected </span><span style="color: #0000BB">string $title</span><span style="color: #007700">;<br />    public protected(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">string $author</span><span style="color: #007700">;<br />    protected private(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">int $pubYear</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">SpecialBook </span><span style="color: #007700">extends </span><span style="color: #0000BB">Book<br /></span><span style="color: #007700">{<br />    public protected(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">string $title</span><span style="color: #007700">; </span><span style="color: #FF8000">// OK, as reading is wider and writing the same.<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">string $author</span><span style="color: #007700">; </span><span style="color: #FF8000">// OK, as reading is the same and writing is wider.<br />    </span><span style="color: #007700">public protected(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">int $pubYear</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal Error. private(set) properties are final.<br /></span><span style="color: #007700">}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </div>
  </div>

  <div class="sect2" id="language.oop5.visiblity-methods">
   <h3 class="title">方法的访问控制</h3>
   <p class="para">
    类中的方法可以被定义为 public、private 或 protected。如果没有设置这些关键字，则该方法默认为 public。
   </p>
   <div class="example" id="example-5">
    <p><strong>示例 #5 方法声明</strong></p>
    <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">/**<br /> * Define MyClass<br /> */<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// 声明一个公有的构造函数<br />    </span><span style="color: #007700">public function </span><span style="color: #0000BB">__construct</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">MyPublic</span><span style="color: #007700">() { }<br /><br />    </span><span style="color: #FF8000">// 声明一个受保护的方法<br />    </span><span style="color: #007700">protected function </span><span style="color: #0000BB">MyProtected</span><span style="color: #007700">() { }<br /><br />    </span><span style="color: #FF8000">// 声明一个私有的方法<br />    </span><span style="color: #007700">private function </span><span style="color: #0000BB">MyPrivate</span><span style="color: #007700">() { }<br /><br />    </span><span style="color: #FF8000">// 此方法为公有<br />    </span><span style="color: #007700">function </span><span style="color: #0000BB">Foo</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyPublic</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyProtected</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyPrivate</span><span style="color: #007700">();<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$myclass </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyClass</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$myclass</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyPublic</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 这行能被正常执行<br /></span><span style="color: #0000BB">$myclass</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyProtected</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 这行会产生一个致命错误<br /></span><span style="color: #0000BB">$myclass</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyPrivate</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 这行会产生一个致命错误<br /></span><span style="color: #0000BB">$myclass</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">Foo</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 公有，受保护，私有都可以执行<br /><br /><br />/**<br /> * Define MyClass2<br /> */<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass2 </span><span style="color: #007700">extends </span><span style="color: #0000BB">MyClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// 此方法为公有<br />    </span><span style="color: #007700">function </span><span style="color: #0000BB">Foo2</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyPublic</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyProtected</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyPrivate</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 这行会产生一个致命错误<br />    </span><span style="color: #007700">}<br />}<br /><br /></span><span style="color: #0000BB">$myclass2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyClass2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$myclass2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">MyPublic</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 这行能被正常执行<br /></span><span style="color: #0000BB">$myclass2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">Foo2</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 公有的和受保护的都可执行，但私有的不行<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Bar <br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">test</span><span style="color: #007700">() {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">testPrivate</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">testPublic</span><span style="color: #007700">();<br />    }<br /><br />    public function </span><span style="color: #0000BB">testPublic</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">"Bar::testPublic\n"</span><span style="color: #007700">;<br />    }<br />    <br />    private function </span><span style="color: #0000BB">testPrivate</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">"Bar::testPrivate\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">Foo </span><span style="color: #007700">extends </span><span style="color: #0000BB">Bar <br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">testPublic</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">"Foo::testPublic\n"</span><span style="color: #007700">;<br />    }<br />    <br />    private function </span><span style="color: #0000BB">testPrivate</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">"Foo::testPrivate\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$myFoo </span><span style="color: #007700">= new </span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$myFoo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">test</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Bar::testPrivate <br />                // Foo::testPublic<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </div>

  <div class="sect2" id="language.oop5.visiblity-constants">
   <h3 class="title">常量的控制访问</h3>
   <p class="para">
    PHP 7.1.0 开始，类的常量可以定义为 public、private 或 protected。如果没有设置这些关键字，则该常量默认为 public。
   </p>
   <div class="example" id="example-6">
    <p><strong>示例 #6 PHP 7.1.0 中的常量声明</strong></p>
    <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">/**<br />* Define MyClass<br />*/<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass<br /></span><span style="color: #007700">{<br />   </span><span style="color: #FF8000">// 公有常量<br />   </span><span style="color: #007700">public const </span><span style="color: #0000BB">MY_PUBLIC </span><span style="color: #007700">= </span><span style="color: #DD0000">'public'</span><span style="color: #007700">;<br /><br />   </span><span style="color: #FF8000">// 受保护的常量<br />   </span><span style="color: #007700">protected const </span><span style="color: #0000BB">MY_PROTECTED </span><span style="color: #007700">= </span><span style="color: #DD0000">'protected'</span><span style="color: #007700">;<br /><br />   </span><span style="color: #FF8000">// 私有常量<br />   </span><span style="color: #007700">private const </span><span style="color: #0000BB">MY_PRIVATE </span><span style="color: #007700">= </span><span style="color: #DD0000">'private'</span><span style="color: #007700">;<br /><br />   public function </span><span style="color: #0000BB">foo</span><span style="color: #007700">()<br />   {<br />       echo </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PUBLIC</span><span style="color: #007700">;<br />       echo </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PROTECTED</span><span style="color: #007700">;<br />       echo </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PRIVATE</span><span style="color: #007700">;<br />   }<br />}<br /><br /></span><span style="color: #0000BB">$myclass </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyClass</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">MyClass</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PUBLIC</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行可以正常执行<br /></span><span style="color: #0000BB">MyClass</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PROTECTED</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行会产生一个致命错误 <br /></span><span style="color: #0000BB">MyClass</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PRIVATE</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行会产生一个致命错误<br /></span><span style="color: #0000BB">$myclass</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 将会输出：Public Protected Private<br /><br /><br />/**<br />* Define MyClass2<br />*/<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass2 </span><span style="color: #007700">extends </span><span style="color: #0000BB">MyClass<br /></span><span style="color: #007700">{<br />   </span><span style="color: #FF8000">// This is public<br />   </span><span style="color: #007700">function </span><span style="color: #0000BB">foo2</span><span style="color: #007700">()<br />   {<br />       echo </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PUBLIC</span><span style="color: #007700">;<br />       echo </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PROTECTED</span><span style="color: #007700">;<br />       echo </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PRIVATE</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行会产生一个致命错误<br />   </span><span style="color: #007700">}<br />}<br /><br /></span><span style="color: #0000BB">$myclass2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyClass2</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">MyClass2</span><span style="color: #007700">::</span><span style="color: #0000BB">MY_PUBLIC</span><span style="color: #007700">; </span><span style="color: #FF8000">// 这行可以正常执行<br /></span><span style="color: #0000BB">$myclass2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo2</span><span style="color: #007700">(); </span><span style="color: #FF8000">// 将会输出：Public Protected，MY_PRIVATE 是私有常量，无法输出<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

  </div>
  </div>

  <div class="sect2" id="language.oop5.visibility-other-objects">
   <h3 class="title">其它对象的访问控制</h3>
   <p class="para">
    同一个类的对象即使不是同一个实例也可以互相访问对方的 private 与 protected 成员。
    这是由于在这些对象的内部具体实现的细节都是已知的。
   </p>
   <div class="example" id="example-7">
    <p><strong>示例 #7 访问同一个对象类型的 private 成员</strong></p>
    <div class="example-contents">
<div class="annotation-non-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">Test<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$foo</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">$foo</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #0000BB">$foo</span><span style="color: #007700">;<br />    }<br /><br />    private function </span><span style="color: #0000BB">bar</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #DD0000">'Accessed the private method.'</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">baz</span><span style="color: #007700">(</span><span style="color: #0000BB">Test $other</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #FF8000">// 我们可以改变 private 属性：<br />        </span><span style="color: #0000BB">$other</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #DD0000">'hello'</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$other</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">);<br /><br />        </span><span style="color: #FF8000">// 我们也可以调用 private 方法：<br />        </span><span style="color: #0000BB">$other</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bar</span><span style="color: #007700">();<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$test </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test</span><span style="color: #007700">(</span><span style="color: #DD0000">'test'</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">baz</span><span style="color: #007700">(new </span><span style="color: #0000BB">Test</span><span style="color: #007700">(</span><span style="color: #DD0000">'other'</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>
string(5) &quot;hello&quot;
Accessed the private method.
</pre></div>
    </div>
   </div>
  </div>
 </div><?php manual_footer($setup); ?>