tags:

views:

55

answers:

3

I have a class:

class test {
    function __construct() {
        print 'hello';
    }
    function func_one() {
        print 'world';
    }
}

what I would like to do is a have a class that sort of extends the test class. I say 'sort of', because the class needs to be able to run whatever function the test class is able to run, but NOT run the construct unless I ask it to. I do not want to override the construct. Anyone has any idea how to achieve this?

+3  A: 
class test {
    function __construct() {
        print 'hello';
    }
    function func_one() {
        print 'world';
    }
}


class test_2 extends test {
    function __construct() {
        if (i want to) {
            parent::__construct();
        }
    }
}
Coronatus
in any case, once you instantiate a new test object, constructor will be executed. i m sorry but this is perhaps misleading.
@user177883: In php you _can_ omit the constructor of the parent class (simply by not calling it explicitly in the constructor of the derived class). I don't like it but that's the way it is.
VolkerK
+1  A: 

What's wrong with overriding the construct?

class foo extends test {
   function __construct() { }
}

$bar = new foo(); // Nothing
$bar->func_one(); // prints 'world'
St. John Johnson
A: 

You could define a "preConstructor" method in your sub-classes that your root-class constructor would execute, and use a boolean flag to determine whether constructor code should be executed.

Like so:

class test
{
    protected $executeConstructor;

    public function __construct()
    {
        $this->executeConstructor = true;
        if (method_exists($this, "preConstruct"))
        {
            $this->preConstruct();
        }

        if ($this->executeConstructor == true)
        {
            // regular constructor code
        }
    }
}

public function subTest extends test
{
    public function preConstruct()
    {
        $this->executeConstructor = false;
    }
}
Adrian
Coronatus' code is functionally equivalent and has less potential for error. However, this will execute the parent constructor by default whereas his won't. Which is preferable is up to Patrick.
outis
@outis: one of the OP's requirements was "I do not want to override the construct." Coronatus' code is not functionally equivalent in that regard.
Adrian
@Adrian: that reads more like part of Patrick's explanation of the phrase "sort of extend" and his idea of how it might work. For one thing, note the phrasing "do not want to" rather than "cannot". Even if that's not the case, it's a design constraint rather than a functional constraint. The ambiguity in the question makes it hard to know which answer is the better fit.
outis
@Adrian: Any additional code that you put in `preConstruct` gets placed in Coronatus's `test_2::__construct`; as long as a coder properly follows your suggestion, the two approaches will produce the same output, and hence are functionally equivalent.
outis
@Adrian: I suppose if some code uses `ReflectionMethod::getDeclaringClass` on the reflection of the constructor for a child class, you could get different results between your approach and Coronatus's, but (as there's no evidence the OP is using reflection and the chances are low that he is) that's about the only way. With every other operation (e.g. creating a new instance, invoking the constructor directly, referencing the constructor as a callback, checking that the method exists on the subclass), the two approaches are functionally indistinguishable.
outis