views:

55

answers:

3

Let's say I have something like this:

abstract class Parent
{
    protected function foobar($data)
    {
        //do something with data
        return $result;
    }
} 

class Child extends Parent
{
    public function foobar()
    {
        $data = ...;

        return parent::foobar($data);
    }
}

As you can see, foobar is generically defined in Parent, and then Child passes class-specific data into the parent which returns the result. The reason this is done is because each child class of parent has its own data, but the method itself remains the same - only the parameter is different. The child also publicly exposes the method.

Is it a better idea to do something like this, where I create a method of the same name in both the parent and the child? Or should I maybe create a _foobar method in the Parent class and just have the Child's foobar method call that?

+2  A: 

First of all, there is no reason for common naming. Call the parent one something like "doFoobarOnGivenData" (you get my drift).

Also, do all the children have the exact same code or is the data cquired differently for each ? It might be better to have a single public foobar method in the parent, that would call an abstract "getDataForFoobar". Each child would then only have to override the way in which data is acquired.

Uri
+1  A: 

This is more of a question of creating an overload versus using a method with similar (but different) name. There's no real "right" answer to this, though I favor the overload.

Adam Robinson
+2  A: 

The The Liskov Substitution Principle states that:

If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T."

Meaning that: Functions that use pointers or references to base classes must be able to do use objects of derived classes without knowing it.

In your example you are violating that by changing the signature of the foobar method (overriding). foobar should have the same signature to the outside world, it can do something different with a related intent. If you need another function then name it something different, Your Child no longer becomes an isa of the Parent.

Romain Hippeau
I don't think he overrided this function (it's not virtual) but overloaded it. it makes difference ;)
Arseny