Class inheritance and visibility:

The PHP manual states:

The visibility of a property or method can be defined by prefixing the declaration with the keywords public, protected or private. Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member.

I understood this to mean that would not inherit private methods/objects. am I mistaken?



<?
class  PrimeAncestor {
    function parent(){// just a constructor
   }
    function fooCall($arg){// for user access
        $this->foo($arg);
   }
   private  function foo($arg){// just a constructor
        echo "am doing something<br>$arg";
   }

}
class child extends PrimeAncestor{
    function child(){// just a constructor
   }
}
$a=new child();
$a->fooCall("HEY YOU!!");
//outputs:
// am doing something
//HEY YOU
?>

I need foo() or fooCall() to be accessible from any instances of the PARENT class but NOT for any descendant classes. AM I missing something about visibility here or there another way to achieve this?

Hi dresden_phoenix,

You are correct about private properties and methods that may only be accessed by the class that defines the member. So in your scenario foo() or fooCall() should be declared private.

Regards,
Steve

Thanks for your reply Steve.

But I guess what I was asking ( and this might seem stupid in retrospect), is how to avoid foo() being inherited, so that it cant be access from child. The issue really comes from the fact that any PUBLIC function is inherited.

So lets say I need to access foo() ,somehow, from an INSTANCE of the parent class, but make it unreachable from an INSTANCE of the child class. If I make a public call function that call function is inherited by the child class, and thus foo() is still accessible (via the call function) to instances of the child class.

NOTE: I know i can redeclare callfoo() in the child class so as not to call foo(), I was just wondering if there was a cleaner way.

I’m curious…if a method should only be used by a certain class…why have children inherit from the class? Or why even concern yourself with it? Simply by never calling the method from the child class to begin with. I think the problem is you are making this all to complex.

Logic,

I tend to do that. Am probably trying to OVER streamline my code. I guess am just searching for best practices.

I am trying to emulate form elements, which means some children will have MOST of the properties /methods of the parent but not all. for example, a <form> can have “class”, “id” and “name” attributes. It also has “action” and “method”. It children have"class", “id” and “name” attributes as well BUT NOT “action” and “method”. It get even more complicated when you realize a form can have " fieldsets" (a method to create this element) and fieldsets can have a method to creat other fieldsets. However, inline children of fieldsets shouldn’t be able to create other fieldsets.

So one dilemma I had was do I use a bunch of independent classes and then repeat the code for the properties /methods they share? The other way, which makes more sense, is to use child classes and block out the properties /methods which are not to be used. I am writing this code not to OUTPUT, per se, but to serve as a coding to for other coders which becomes a concern.

Anyway, I have come up with 4 different solutions that “work” but also “fail” in some regards. This is what the END USER would see ( whit the comments being my results/intention)

$a=new form();

  1. Do not use related classes. Seems primitive, and there is much redundant code many of the same methods/properties are declared multiple times. Also causes fatal errors when used improperly. ( not leaning to ward this on at all)
    $a->makeFieldset();// works! makes fieldset
    $a->makeFieldset()->makeFieldset();//works! makes fieldset (inside the first)
    $a->makeFieldset()->makeFieldset()->makeControl();//works! makes control
    $a->makeFieldset()->makeFieldset()->makeControl()->makeFieldset;// FAILS(as supposed to)! Gives fatal ERROR!!

  2. Use related classes. Sleeker code, but there is unwanted method/property inheritance.
    $a->makeFieldset();// works! makes fieldset
    $a->makeFieldset()->makeFieldset();//works! makes fieldset (inside the first)
    $a->makeFieldset()->makeFieldset()->makeControl();//works! makes control
    $a->makeFieldset()->makeFieldset()->makeControl()->makeFieldset;// works! , but it’s not supposed to, makes fieldset (inside the control element))!

  3. Use Related classes, OVERWRITE the unwanted function/attributes in child classes ala foo(){return:false;}/ unset( $this->att). There are quite a few levels and quite a few functions so it seemed a bit convoluted. However this odes have the added UI benefit that I can echo out error messages w/o fatal error being thrown.
    $a->makeFieldset();// works! makes fieldset
    $a->makeFieldset()->makeFieldset();//works! makes fieldset (inside the first)
    $a->makeFieldset()->makeFieldset()->makeControl();//works! makes control
    $a->makeFieldset()->makeFieldset()->makeControl()->makeFieldset;// fails! as intended… echos error message instead and continues on to other code.

  4. wrap a PRE-ROOT class! Should have thought of that before! and BRANCH children out of it. it took 200 lines of code out of my project. No function is declared more than once; it’s sleek and graceful… but not very forgiving. Alas, too successful, the ONE downfall: because the methods/classes are entirely absent they cause fatal errors when the code is written incorrectly.
    $a->makeFieldset();// works! makes fieldset
    $a->makeFieldset()->makeFieldset();//works! makes fieldset (inside the first)
    $a->makeFieldset()->makeFieldset()->makeControl();//works! makes control
    $a->makeFieldset()->makeFieldset()->makeControl()->makeFieldset;// FAILS(as supposed to)! Gives fatal ERROR!!

Obviously, control classes/elements need to inherit from a different base class then “form” or “fieldset”. Or a more generic base class. One that only has the bare essentials. Or what I would do…have generic handling of attributes. ( setAttribute( $name, $value ) ) Type deal. Then it won’t matter if a control or element supports an attribute or not. But controls should not inheirt from “form” class.

…have generic handling of attributes. ( setAttribute( $name, $value ) )

Thanks In a sense , that’s kinda what I ended up doing for opt #3. Except I targeted the handler that creates the child object all together. In other words, a control element , when asked to create a container element simply returns false. I did this by re declaring the method in the control element. It’s just that it seemed kinda clumsy ( especially when you have about a 10 inherited method to reset at times).


class form{
   function  makefieldset(){...makes fielset}
   function ouputThisLevel(){ outputs levels recursively }
}
class fieldset extends form{ // fieldsets can make more fieldsets
}
class control extends fieldset{
   function  makefieldset(){return false;}// controls aren't supposed to make fieldsets
}

This also works, but as I said it’s less forgiving:


class uberForm{
   function ouputThisLevel(){ outputs levels recursively }
}
class form{
   function  makefieldset(){...makes fielset}
}
class fieldset extends form{ 
}
class control extends uberForm{
}