Question

I was reading through some PHP code, and I noticed a class calling a protected method on its sibling (inherited from a common parent). This strikes me as counter-intuitive.

Does in the same inheritance tree in PHP mean something like Java's part of the same package ?

I'm more used to the C# meaning of protected.

Because I am more used to C#'s meaning of protected, I was not expecting to be able to call the protected method on a sibling class. In Java, the distinction is clear from the package. Is there anything, other than inheritance, that defines accessibility in this instance in 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

Here's me trying to the same thing in C# (and failing).

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();
        }
    }
}

It looks like the behaviour expected was the case prior to PHP 5.2. This RFC explains the issue a little more, and points to why the change happened in this bug.

I'm not sure it quite answers my question, but I thought I'd update the question, in case it helps anyone.

Thanks to Robin F., for pointing me to this discussion of the RFC, for some background.

Was it helpful?

Solution 2

It looks like the behaviour expected was the case prior to PHP 5.2. This RFC explains the issue a little more, and points to why the change happened in this bug.

I'm not sure it quite answers my question, but I thought I'd update the question, in case it helps anyone.

Thanks to Robin F., for pointing me to this discussion of the RFC, for some background.

OTHER TIPS

To me there isn't nothing out-of-order. protected means visible to this class and all his subclasses.

Let's analyze this snippet

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";
  }
}

You're overwriting C1->f() [and this is fine] but first time you're recalling $c1->f() (as $c1 is an instance of C1 class) and so output is perfectly ok.
Second time you're calling $c2->f() so no sibling function but C2 class function and this is perfectly legal as you're overwriting this too.

Maybe I don't understand properly your question, but this is the explaination of the above snippet of code

According to Wikipedia (http://en.wikipedia.org/wiki/Php):

Objects of the same type have access to each other's private and protected members even though they are not the same instance.

EDIT:

See code snippet (in 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!");
    }
}

When run, in the console there will be message displayed.
I guess this is because of how compilator (or for PHP interpreter) is implemented.

In this case you are inside SimpleApp class, so you can call its private method (even on different object - from outside). It might be different for C#.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top