我正在阅读一些PHP代码,我注意到一个类在其兄弟上调用受保护的方法(继承自普通父代)。这让我感到反直觉。
PHP中的in the same inheritance tree
是否意味着like Java's part of the same package
?
I'm more used to the C# meaning of protected
.
因为我更习惯于C#的protected的含义,所以我没想到能够在兄弟类上调用受保护的方法。在Java中,包的区别很明显。除了继承之外,还有什么能在PHP中定义此实例中的可访问性吗?
<?
class C1
{
protected function f()
{
echo "c1\n";
}
}
class C2 extends C1
{
protected function f()
{
echo "c2\n";
}
}
class C3 extends C1
{
public function f()
{
// Calling protected method on parent.
$c1 = new C1();
$c1 -> f();
// Calling protected method on sibling??!?
$c2 = new C2();
$c2 -> f();
echo "c3\n";
}
}
$c3 = new C3();
$c3 -> f();
// OUTPUT:
// c1
// c2
// c3
这是我在C#中尝试同样的事情(并且失败了)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class c1
{
protected void f()
{
Console.WriteLine("c1");
}
}
class c2: c1
{
protected void f()
{
Console.WriteLine("c2");
}
public void g()
{
Console.WriteLine("g!");
}
}
class c3 : c1
{
protected void f()
{
// Error 1 Cannot access protected member 'ConsoleApplication2.c1.f()'
// via a qualifier of type 'ConsoleApplication2.c1'; the qualifier must be
// of type 'ConsoleApplication2.c3' (or derived from it)
//c1 cone = new c1();
//cone.f();
base.f();
c2 ctwo = new c2();
//Error 1 'ConsoleApplication2.c2.f()' is inaccessible due to its protection level
ctwo.f();
ctwo.g();
Console.WriteLine("c3");
}
}
class Program
{
static void Main(string[] args)
{
c3 cthree = new c3();
// Error 2 'ConsoleApplication2.c3.f()' is inaccessible due to its protection level
cthree.f();
}
}
}
看起来预期的行为就是PHP 5.2之前的情况。 This RFC explains the issue a little more,并指向why the change happened in this bug。
我不确定它是否完全回答了我的问题,但我想我会更新这个问题,万一它可以帮助任何人。
感谢Robin F.,pointing me to this discussion of the RFC,感谢某些背景。
答案 0 :(得分:1)
对我而言,没有任何乱序。 protected
表示此类及其所有子类都可见。
让我们分析一下这个片段
class C3 extends C1
{
public function f()
{
// Calling protected method on parent.
$c1 = new C1();
$c1 -> f();
// Calling protected method on sibling??!?
$c2 = new C2();
$c2 -> f();
echo "c3\n";
}
}
你正在覆盖C1->f()
[这没关系]但是第一次回忆$c1->f()
(因为$c1
是C1
类的实例)所以输出完全没问题。
第二次你打电话给$c2->f()
所以没有兄弟功能,但C2
类功能,这是完全合法的,因为你也覆盖了它。
也许我不能正确理解你的问题,但这是对上述代码片段的解释
答案 1 :(得分:0)
看起来预期的行为就是PHP 5.2之前的情况。 This RFC explains the issue a little more,并指向why the change happened in this bug。
我不确定它是否能完全回答我的问题,但我认为我会更新问题,以防万一。
感谢Robin F.,pointing me to this discussion of the RFC,感谢某些背景。
答案 2 :(得分:-1)
根据维基百科(http://en.wikipedia.org/wiki/Php):
相同类型的对象可以访问彼此的私有成员和受保护成员,即使它们不是同一个实例。
修改强>
请参阅代码段(在 Java 中):
public class SimpleApp {
public static void main(String[] args) {
SimpleApp s = new SimpleApp();
s.method(); // interesting?!
}
private void method() {
System.out.println("This is private method!");
}
}
运行时,在控制台中会显示消息 我想这是因为compilator(或 PHP 解释器)的实现方式。
在这种情况下,您位于SimpleApp类中,因此您可以调用其私有方法(即使在不同的对象上 - 来自外部)。 C#可能有所不同。