我正在用PHP修改我的OOP概念。我在这里有一个简单的PHP代码来实现可见性。
当我在Big_Animal中声明$ name为private时,
1)为什么当我尝试从类外部为$ name分配不同的值时,它不会抛出错误(即$ lion-> name =“King”)?
2)当我尝试在Lion类中重新分配$ name时,为什么它不会抛出错误(即$ this-> name =“John”)。
据我所知,我很困惑,只能在定义属性的类中访问私有属性。
我不清楚的另一件事是受保护的属性。根据我的理解,受保护的属性只能在类本身及其子类中访问。可以通过孙子课程访问吗?
谢谢。
<?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();
?>
答案 0 :(得分:3)
答案 1 :(得分:3)
您的魔术方法访问器(__set和__get)在基类抽象类中是公共的。当您直接访问该属性时,他们是写入私有数据的人。尝试评论魔术方法,看看。然后,输出是“名字:玛丽我是狮子!吼!”。
将此添加为Lion :: Describe()中的第一个语句:
回声“狮子的名字:”。 $ this-&gt;名称。 “\ n” 个;正如您所看到的,输出现在是:“Lion的名字:King”。两个$ this-&gt; name =“John”;和$ lion-&gt; name =“King”;正在修改Lion类对象的公共属性。不幸的是,你可以拥有同名的公共和私人财产,但你可以。它们只是不同的变量(在不同的范围内)。
可以从孙子访问受保护的属性。除非您有足够的理由保护它(因此使用私有),否则您的大部分属性都应受到保护。公共属性在较大的项目中使用不多(取决于您的风格)。我宁愿坚持使用显式访问器。随着项目的进展和变得越来越复杂,您会很高兴您选择为每个变量使用访问器。我更喜欢使用一个生成脚手架访问器的生成器。它节省了大量时间,减少了错误,并使访问者的创建更便宜(因此更常见)。
更新(对以下评论的回复): 1)和2)你没有得到错误,因为你在我上面2)中列出的两个实例中编辑了Public变量。尝试var_dump($ lion):
object(Lion)#1 (2) {
["name":"Big_Animal":private]=>
string(4) "Mary"
["name"]=>
string(4) "John"
}
此外,如果您向Lion类显式添加私有或受保护的成员变量,您将收到预期的错误。我同意你的看法,这不是很直观,但似乎是PHP当前的现实。
3)http://www.ibm.com/developerworks/opensource/library/os-php-7oohabits/有一个为私有成员变量编写公共访问器的例子(尽管如此,我建议再为受保护的成员变量编写公共访问器)。
答案 2 :(得分:1)
详细说明我的评论...你正在使用一个名为__set的函数,这样做的是每当你尝试在这个类的未知属性上设置一个值时,就会调用这个特定的函数。
在您的函数中,您始终将私有字段名称更改为提供的值。由于此类可以访问它的字段,因此已设置。
即使您写了$ lion-&gt; foo =“bar”,由于您的函数__set
,名称也会设置为bar答案 3 :(得分:-3)
我认为您的问题的答案是here
抽象方法不能是私有的,因为根据定义它们必须是私有的 由派生类实现。如果你不希望它是公开的,它 需要保护,这意味着它可以通过派生来看待 课程,但没有其他人。