Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 4 of 4
  1. #1
    Senior Coder
    Join Date
    Jun 2008
    Location
    New Jersey
    Posts
    2,546
    Thanks
    45
    Thanked 259 Times in 256 Posts

    Passing properties from abstract parents

    So I have a basic abstract class which has a few abstract functions, a set function, and a few properties I want the children classes to contain.

    PHP Code:
    abstract class Roll {
        private 
    $rolls = array();
        private 
    $dice = array();

    /* Methods are here, some abstract, some not */

    When I try to access either of these two properties from a child class, they show up as not existing:

    PHP Code:
    class BasicRoll extends Roll {
        function 
    __construct() {
            
    var_dump($this->roll); /* Returns NULL */
        
    }

    Am I not understanding something about abstract classes? Is there a method of inheritance here I don't know? Is there a way to make sure these variables exist? My only other thought is to put them in the constructor, but that seems a weird way to do it. Another thought was to make the parent class not abstract, give it empty functions instead of abstract ones, and a private constructor, but that seems like a REALLY hacky way of doing it.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Its not the abstraction you're not understanding, its the scope.
    Private methods/members are visible to *this class* only. If you want a child to view the method or member property, than you need to use a protected scope.

    You're second way (which you suggest is hacky), isn't at all hacky. Unless you have something of value to provide within an abstract, its rarely desirable to use one.

    PHP Code:
    interface IRoll
    {
        public function 
    doSomething();

    Is far more ideal than:
    PHP Code:
    abstract class Roll
    {
        public abstract function 
    doSomething();

    The former allows multiple inheritance while the latter does not.

    I've actually a situation where I have an abstract class with no abstract functions, which is designed to place base level functionality with a finer grain approach without forcing the children to do as much work:
    PHP Code:
    interface IFilter
    {
        public function 
    execute(IFilterChain $chain);
    }

    abstract class 
    AFilter implements IFilter
    {
        public function 
    execute(IFilterChain $chain)
        {
            
    $this->preFilter();
            
    $chain->execute();
            
    $this->postFilter();
        }

        protected function 
    preFilter()
        {
        }

        protected function 
    postFilter()
        {
        }

    Obviously a lot more to it than this, but the idea is that I have an abstract filter which takes care of establishing the pre and post filtering of the chain, and the children can execute their execute() command while implementing either the pre, post or both functions without forcing any to be provided. This is simply an adapter technique, but I rarely suggest that abstracts be used in this manner (other than for creating minimum implementation adapters, otherwise the abstract should have abstraction within it).
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #3
    Senior Coder
    Join Date
    Jun 2008
    Location
    New Jersey
    Posts
    2,546
    Thanks
    45
    Thanked 259 Times in 256 Posts
    So different Rolls do have methods in common (such as some of the getters). Its why I thought to use an abstract parent. I was thinking of using an interface, but in my scenario, multiple inheritance isn't necessary, and as mentioned, there are some common methods.

    To clarify on one point, you're suggesting that creating a parent class with a private constructor (so it can't be accidentally created) isn't hacky? I'm sure its my inexperience speaking, but it feels a bit wrong. If not, maybe its the way to go for me.

    And to clarify on scope: so a private variable isn't inherited, and is unique to the class that contains it, but a protected variable is passed down to child classes, but is still not accessible from outside like a private property?

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    No no, a concrete class with a private constructor isn't a good idea. What I was getting at is that if you would do that, then simply use an interface. An alternative is to use the adapter approach with the abstract so that you can implement whatever you want and force what you require.
    PHP has very limited scope options:
    private - this class
    protected - this class and inherited class
    public - any where
    Private is the most useful. I rarely implement protected members but often implement protected methods. I would choose instead to provide a protected method in a parent class that the child classes now require to make use of in order to alter the members defined by a parent. This is simply because I assume any class will not be extended, but only force the extension block if absolutely necessary.

    Ultimately, a class or interface is a datatype. So when I tell you I'm a typeof IRoll, I would provide you with a guarantee that I will implement the methods provided by the IRoll contract. It doesn't matter if IRoll is an interface, abstract, or concrete class, it will guarantee the methods provided (well, baring known bugs that can occur). For this reason, child class methods should rarely be relied on since the power comes from the flexible design of the inheritance. So if I had a Dice class, I would never invoke a method defined directly from the SixSidedDie class or TwelveSidedDie class, I would invoke a method from the IDie interface. The use of the abstract can simply be thought of as a base skeleton implementation of an interface where the abstracts provided may not be a direct pass over from an interface or publicly callable, and instead could be invoked by a public method. Abstracts definitely have their place, but if there's ever any doubt than the answer is an interface (in a language like PHP implements is far more valuable than extends).
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •