3

in an effort to further my understanding of OOP, I've decided to refactor some of my code using an abstract class. The idea is roughly;

  • One "parent" abstract class which forms a base for all child classs' to extend.
  • One "helper" class which has a series of methods which children of the abstract class will need.
  • the "helper" class will be used by other classes, so I don't want this to be an integral part of the abstract class.

The problem;

The child class extends the abstract class as intended, but PHP gives me a warning that the $helper argument is missing from the abstract class's constructor. I believe the constructor is being called because there isn't one in my child class, which is fine, but since you don't directly call an abstract class, how do I get this to work? Sample code below;

abstract class Parent_Abstract
{
    public $input_helper_methods;

    public function __construct( $helpers = NULL )
    {

        //set the helper methods
        $this->input_helper_methods = $helpers;

    }
}

The variable $helpers is in another file at the moment, which is included at the top of the file with the abstract class. Again, I think there's an issue with how this is being done. When I understand the structure I would like to use an autoloader, but for now, just manual would be good. This is the contents of that file;

class RD_Form_Input_Helper_Methods
{
    private $var = 'something';
}

$helpers = new RD_Form_Input_Helper_Methods;

I hope this makes some sense. Thanks for taking the time to read/reply.

Another example;

//"helper" classes. I would like these methods to be available to Child_One and Child_Two
class Helper_Functions {}

class Formatting_Functions {}


abstract class Parent_Abstract()
{
    private $helper_functions;
    private $formatting_functions;

    public function __construct( $object_one, object_two )
    {
        $this->helper_functions = $object_one;
        $this->helper_functions = $object_two;
    }

}

class Child_One extends Parent_Abstract 
{
    //I can use any of the properties or methods from the Helper_Functions or Formatting_Function class
}

class Child_Two extends Parent_Abstract 
{
    //I can use any of the properties or methods from the Helper_Functions or Formatting_Function class
}
1
  • Nope. I've seen your reply in the answer below and replied there. Commented Oct 11, 2014 at 16:29

2 Answers 2

2

The child class extends the abstract class as intended, but PHP gives me a warning that the $helper argument is missing from the abstract class's constructor.

You would only get such a warning if the abstract class constructor would require the $helper parameter. But your code is different, the $helper parameter is optional:

abstract class Parent_Abstract
{
    public $input_helper_methods;

    public function __construct( $helpers = NULL )
    {                            ###############      $helpers is optional

Now as I quote it, it also has a different name $helper =/= $helpers.

So most likely the code example you give in your question is incomplete and with errors.

Let's just outline a new one modeled after your question:

abstract class AbstractBaseClass
{
    private $helper;

    function __construct($helper)
    {
        $this->helper = $helper;
    }
}

class Concrete extends AbstractBaseClass
{
}

The differences in short: the $helper field (or property) is private and not public; the $helper ctor parameter is required.

Using that code and instantiating a concrete childclass is giving your said error:

// Warning: Missing argument 1 for AbstractBaseClass::__construct()

$obj = new Concrete();

That is because the helper is missing. To make this very simple, let's assume the helper is actually a secret number you need in complex calculations all done by such concrete classes. The number is 42:

$obj = new Concrete(42);

Now the error is gone. And the helper field is properly initialized:

print_r($obj);

Concrete Object
(
    [helper:AbstractBaseClass:private] => 42
)

As you can see, the private field of the abstract class has been set. The helper (here the number 42) has been assigned to it.

Sign up to request clarification or add additional context in comments.

Comments

-1

What you're looking for is static variables.

In this example I'm using a variable called $text rather than your original $helpers. The variable, once set will be the same in all child classes.

Define an abstract class with a public static variable. Also, optionally define a getter function, this will allow you to access the static variable's value as a property on each child class.

abstract class Parent_Abstract
{

    public static $text;

    public function __get($name)
    {
        // return the static variable's value
        return $name == 'text' ? self::$text : null;
    }
}

Define 2 child classes:

class Child1 extends Parent_Abstract
{

}

class Child2 extends Parent_Abstract
{

}

Now to test... Set the value of the static variable, then instantiate the child classes and check the value of $text on each object;

Parent_Abstract::$text = 'hello world';

$child1 = new Child1();
$child2 = new Child2();

echo $child1->text . "\n";
echo $child2->text;

You will see the value is the same for both children.

13 Comments

Hi, thanks for the reply. I've previously tried this, it's working ok. I'm trying to pass the $helpers object directly to the abstract class so I don't have to pass it via the child classes, although I guess I'd only have to pass it once? Confusing...
@Dan: Your comment makes me wondering a little: How do you pass $helpers directly to the abstract class? An abstract class normally does not "exist". - but if I get you now right: You pass to there through inheritance (parent::...) and you only pass it once, because there is only one object, not to. it's only compound of the abstract base class and the extending class, but it's one object. At runtime you normally don't care about that much. for the application there is no difference if there was a base-class or not.
@hakre - I understand the idea that the abstract class doesn't "exist". Maybe what it's my head just can't be done? I'd like to combine the functionality of one class with the abstract class, then inherit from it.
Drahcir: I'm perfectly sure @Dan is not looking for static variables.
well folks, I guess the problem is far easier. and don't throw language features onto it, just try to sort it out with the more basic elements. keep statics, traits and the like away as much as possible. basic inheritance, visibility and probably the concept of an abstract base class / interface are quite something for starters already.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.