douhoujun9304 2012-08-03 06:35
浏览 46
已采纳

php oops:可见性

I'm revising my OOPs concepts in PHP. I have a simple php code here for practising visibility.

When i declare $name as private in Big_Animal,

1)Why it doesn't throw an error when i try to assign a different value for $name from outside the class (ie. $lion->name="King")?

2)Why it doesn't throw an error when i try to reassign $name in Lion class (ie. $this->name="John").

I'm confused coz as per my knowledge, private properties can only be accessed within the class that defines the property.

The other thing i'm not clear about is protected properties. As per my understanding, protected properties can be accessed only within the class itself and its child classes. Can it be accessed by its grandchild classes?

Thank you.

<?php
abstract class Big_Animal{

 private $name="Mary";

  abstract public function Greet();

 public function Describe(){
    return "name: ".$this->name;
}

public function __set($name,$value){
    $this->name=$value;
}

public function __get($name){
    return $this->name;
}
}

class Lion extends Big_Animal{


public function Greet(){
    $this->name="John"; //no error for this
    return " roar!";
}



public function Describe(){
        return parent::Describe()." I'm a Lion!";
    }
}


$lion = new Lion();
$lion->name="King";  //no error for this
echo $lion->Describe();
echo $lion->Greet();

?>
  • 写回答

4条回答 默认 最新

  • drztpx8735 2012-08-03 06:55
    关注
    1. Your magic method accessors (__set and __get) are public in the base, abstract class. They are the ones writing to the private data when you access the property directly. Try commenting out the magic methods and see. Then, the output is "name: Mary I'm a Lion! roar!".

    2. Add this as the first statement in Lion::Describe():

      echo "Lion's name: " . $this->name . " ";

      As you can see, the output is now: "Lion's name: King". Both $this->name="John"; and $lion->name="King"; are modifying the public property on Lion class' object. It's unfortunate that you can have both public and private properties of the same name, but you can. They are simply different variables (in different scopes).

    3. Protected properties can be accessed from grandchildren. Most of your properties should be protected, unless you have a really strong reason to protect it (therefore using private). Public properties aren't used much in larger projects (depending on your style). I'd prefer to stick with explicit accessors. As a project progresses and becomes more complex, you'll be glad you chose to use accessors for each variable. I prefer to use a generator that will generate the scaffolding accessors for you. It saves a lot of time, cuts down on errors, and makes the creation of accessors a lot cheaper (and therefore more common).

    UPDATE (a response to the comment below): 1) and 2) You're not getting errors because you're editing the Public variable in both of the instances that I listed in my 2) above. Try var_dump($lion):

    object(Lion)#1 (2) {
      ["name":"Big_Animal":private]=>
      string(4) "Mary"
      ["name"]=>
      string(4) "John"
    }
    

    Also, if you explicitly add a private or protected member variable to the Lion class, you will get the error that you expect. I would agree with you that that's not very intuitive, but appears to be the current reality in PHP.

    3) http://www.ibm.com/developerworks/opensource/library/os-php-7oohabits/ has an example of writing public accessors for private member variables (although, again, I'd recommend writing public accessors for protected member variables instead).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型
  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器