<?php
/**
* Define MyClass
*/
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}$obj = new MyClass();
echo $obj->public; // 这行能被正常执行
echo $obj->protected; // 这行会产生一个致命错误
echo $obj->private; // 这行也会产生一个致命错误

$obj->printHello(); // 输出 Public、Protected 和 Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
    // 可以对 public 和 protected 进行重定义,但 private 而不能
    protected $protected = 'Protected2';    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}$obj2 = new MyClass2();
echo $obj->public; // 这行能被正常执行
echo $obj2->private; // 未定义 private
echo $obj2->protected; // 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2,但不会输出 Privateclass Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?> 
这个红色部分不是很明确obj既然是MyClass的实例,为什么三个属性变量只有public的属性可以访问啊?
protected private的变量为什么访问不了

解决方案 »

  1.   

    代码之前的描述:
    访问控制
    对属性或方法的访问控制,是通过在前面添加关键字 public、protected 或 private 来实现的。由 public 所定义的类成员可以在任何地方被访问;由 protected 所定义的类成员则可以被其所在类的子类和父类访问(当然,该成员所在的类也可以访问);而由 private 定义的类成员则只能被其所在类访问。 对类成员的访问控制
    类成员都必须使用关键字public、protected 或 private 进行定义 
      

  2.   

    obj是这个类实例化的对象,为什么这个类的protected,private属性的变量无法访问?
    又不是说obj是其他什么类的实力,如果是其他类,不是子类父类关系,那么private的肯定无法访问
    是子夫类的,那么protected是可以访问的。
    我就不明白啊
    本身类实例话的对象,怎么自己的变量无法访问。手册说明了吗?
      

  3.   

    <?phpclass foo
    {
        public function printItem($string) 
        {
            echo 'Foo: ' . $string . PHP_EOL;
        }
        
        public function printPHP()
        {
            echo 'PHP is great.' . PHP_EOL;
        }
    }class bar extends foo
    {
        public function printItem($string)
        {
            echo 'Bar: ' . $string . PHP_EOL;
        }
    }$foo = new foo();
    $bar = new bar();
    $foo->printItem('baz'); // Output: 'Foo: baz'
    $foo->printPHP();       // Output: 'PHP is great' 
    $bar->printItem('baz'); // Output: 'Bar: baz'
    $bar->printPHP();       // Output: 'PHP is great'?> 
    就这么一个例子(除了后面的评论),这个也好理解。bar扩展了foo,又因为bar的方法printItem签名和父类foo是一样的,所以就覆盖了父类的方法了。如果签名不一样,那么父类的方法printItem也会继承,并且根据方法签名的不同选择使用继承过来的父类方法printItem还是bar自己有的方法printItem......
    想不通啊
      

  4.   

    在想该怎么解析好打个比方,class是电脑(硬盘、内存、CPU...)
    new把它封装,加个外壳,加不同的壳就是不同牌子电脑内CPU与内存可以互相访问,但加壳后,使用者就只能通过键盘、鼠标操作把数据传递给CPU\内存
    但操作者直接接根电线到cpu上面就是个问题,所以对cpu设定只能内部访问这就是面向对象,实例化后就算作“外部”了大概意思,举例不太严谨
      

  5.   

      protected $protected = 'Protected';
      private $private = 'Private';
    看看,第一个是本类和子类可以借用,第二个是只有本类内部可以调用,你那样访问当然出错了,权限不允许你访问,你该成public 就好了,就如同单例一样
      

  6.   

    "这就是面向对象,实例化后就算作“外部”了"
    就这里不理解了,实例化反而不是内部的了,呵呵。
    怎么感觉跟JAVA那神马好像不一样
      

  7.   

    <?php
    class ClassOne {
        protected static $staticone = 'nathan';
        protected function changestaticone()
         {
            return self::$staticone = 'john';
           
         }  
       
    }class ClassTwo extends ClassOne
     {
        public function changestaticone()
         {
            return self::$staticone = 'Alexey';
        }
          

    echo ClassOne::changestaticone(); //放在这里回报错
    ?>
    ------------------
    changestaticone()这个方法怎么访问?
      

  8.   

    protected static $staticone = 'nathan';
    你这个权限要是public的
      

  9.   

    说错了,是那个函数要是public的,因为你想要单例必须有一个方法供外部调用
      

  10.   

    class ClassOne {

    private function __construct(){}//要想单例,构造函数必须私有(即不可被实例) public function changestaticone(){//但必须要有个公有的方法给其他程序调用来达到实例该类的效果
    static $staticone;
    if(!$staticone){
    $staticone = new ClassOne();//因为是自身实例的自己所以没有private限制
    }
    return $staticone;
    }
    }ClassOne::changestaticone();