Jump to content

Does polymorphism really help?


dennis-fedco
Go to solution Solved by KevinM1,

Recommended Posts

I want to avoid hardcoding things like this:

     if ($product == "APPLE") $res = $this->doAppleComputation();
else if ($product == "PEAR") $res = $this->doPearComputation();
else if ($product == "KIWI") $res = $this->doKiwiComputation();
...

Note that I can also set it up using a switch statement.  Typical advice that I have seen is "do not use switch/if/then/else, use polymorphism".

Okay.  So I used it and I get this:

     if ($product == "APPLE") $res = (new Apple())->compute();
else if ($product == "PEAR") $res = (new Pear())->compute();
else if ($product == "KIWI") $res = (new Kiwi())->compute();
...

I am not quite seeing the benefit . . .

What am I missing?

 

My goal is to not have if/then/else/switch statements, as polymorphism was supposed to get rid of that, no?

Edited by dennis-fedco
Link to comment
Share on other sites

Polymorphism does not magically make all switch statements superfluous. If you want to instantiate different classes depending on a parameter, well, then you need to refer to those different classes.

 

The only way to avoid a switch statement would be to make the class name dynamic:

$some_class = 'A';
$a = new $some_class();

But that's not exactly pretty, either. If you take this route, you should definitely check if the parameter indeed refers to a subclass of the product class. Otherwise, you may end up with any class.

Link to comment
Share on other sites

Assuming all of your fruit classes extend or implement product, it looks like you should be using the factory pattern. Create a ProductFactory class that takes in the $product and returns the correct object.

Link to comment
Share on other sites

I agree with Maq. What you've described above isn't really polymorphism (at least not so much as I understand the concept). What you'd do is create Apple, Pear, and Kiwi class files, the approach like this:

$fruit = 'Apple';
$produce = new $fruit();
$res = $produce->calculate();

$fruit = 'Kiwi';
$produce = new $fruit();
$res = $produce->calculate();

$fruit = 'Pear';
$produce = new $fruit();
$res = $produce->calculate();

This way Apple,. Kiwi, and Pear can all have wildly different methods of calculating whatever it is they're calculating and the calling implementation doesn't have to know a thing about any of it.

Edited by maxxd
Link to comment
Share on other sites

  • Solution

What you've described above isn't really polymorphism

This. Polymorphism is about being able to have different classes that perform the same task at runtime. Take the following example:

 

abstract class Person
{
    private $name;
    private $salary;

    public function __construct($name, $salary)
    {
        $this->name = $name;
        $this->salary = $salary;
    }

    abstract public function calculateRaise();
}

class Employee extends Person
{
    public function calculateRaise()
    {
        $this->salary += 1000;
    }
}

class Boss extends Person
{
    public function calculateRaise()
    {
        $this->salary += 100000;
    }
}

class PersonFactory
{
    private $db;

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

    public function getPerson($id)
    {
        // query the db to get the person info
        // determine what kind of person to return based on a flag or something

        $person = new $row['role']();

        // fill the person with the rest of the data

        return $person;
    }
}

$factory = new PersonFactory($db); // assuming we instantiated our db somewhere else
$people = array(22, 54656, 99, 675, 1009); // person ids

foreach ($people as $personID) {
    $person = $factory->getPerson($personID);
    $person->calculateRaise();

    // save the person to the db
}
Yeah, the example is canned, and probably has some syntax issues, but you get the idea. The whole point of polymorphism is to hide implementation behind a common API. The loop that gives raises to those people doesn't care if they're an Employee or a Boss. Why should it? So long as a Person can get a raise, does it matter if they're an Employee, Boss, or something else, like a Contractor? No.

 

At some point, you'll need to make a determination about what kind of object to construct. That's generally where factories come in. Their entire purpose is to return a concrete object for the program to use. But, with polymorphism, you'll only be seeing and dealing with the functionality laid out by the abstract base class or interface.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.