Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

General Polymorphism with PHP examples

As only Dogs can play "fetch", is this example a good or a bad idea? I suspect it's a really bad idea due to the usage of instanceof, but I'm not entirely sure why.

class Animal {     var $name;     function __construct($name) {         $this->name = $name;     } }  class Dog extends Animal {     function speak() {         return "Woof, woof!";     }      function playFetch() {         return 'getting the stick';     } }  class Cat extends Animal {     function speak() {         return "Meow...";     } }  $animals = array(new Dog('Skip'), new Cat('Snowball'));  foreach($animals as $animal) {     print $animal->name . " says: " . $animal->speak() . '<br>';     if ($animal instanceof Dog) echo $animal->playFetch(); } 

Another example. As I am constantly creating data objects that have an ID, I figured I might as well extend them all from a base class to avoid code duplication. Again, this was bad right? As a Chair doesn't have a name and a Dog doesn't have wheels. But they are both Data Objects so it's very confusing.

class Data_Object {     protected $_id;      function setId($id) {         $this->_id = $id;     }      function getId() {         return $this->_id;     } }  class Dog extends Data_Object {     protected $_name;     function setName($name) {         $this->_name =      }      function getName() {         return $this->_name;     } }  class Chair extends Data_Object {     protected $_numberOfWheels;     function setNumberOfWheels($number) {         $this->_numberOfWheels = $number;     }      function getNumberOfWheels() {         return $this->_numberOfWheels;     } } 

Essentially what I think I'm asking is: "should all subclasses have the same interface or can they have different ones?"

like image 985
Dan Avatar asked Dec 17 '11 04:12

Dan


People also ask

What is polymorphism example in PHP?

Polymorphism portrays an example in object-oriented programming where methods in various classes that do similar things should have a similar name. Polymorphism is essentially an OOP pattern that enables numerous classes with different functionalities to execute or share a commonInterface.

How many types of polymorphism are there in PHP?

There are two types of Polymorphism; they are: Compile time (function overloading) Run time (function overriding)

Does PHP allow polymorphism?

Polymorphism in PHP can be implemented by either the use of interfaces or abstract classes.

How polymorphism is achieved in PHP?

Polymorphism allows objects of different classes to respond differently based on the same message. To implement polymorphism in PHP, you can use either abstract classes or interfaces. Polymorphism helps you create a generic framework that takes the different object types that share the same interface.


1 Answers

In this context it's useful to talk about interfaces.

interface Talkative {     public function speak(); }  class Dog extends Animal implements Talkative {     public function speak() {         return "Woof, woof!";     } } 

Any animal or human (or alien) that implements the Talkative interface can be used in a context where talkative beings are needed:

protected function makeItSpeak(Talkative $being) {     echo $being->speak(); } 

This is a properly used polymorphic method. You don't care what you're dealing with as long as it can speak().

If Dogs can also play fetch, that's great for them. If you want to generalize that, think about it in terms of an interface as well. Maybe one day you'll get a highly trained cat which can play fetch as well.

class Cog extends Cat implements Playfulness {     public function playFetch() { ... } } 

The important point here being that when you call playFetch() on something, it's because you want to play fetch with that animal. You don't call playFetch because, well... you can, but because you want to play fetch in this very moment. If you don't want to play fetch, then you don't call it. If you need to play fetch in a certain situation, then you need something that can play fetch. You ensure this through interface declarations.

You can achieve the same thing using class inheritance, it's just less flexible. In some situations where rigid hierarchies exist though it's perfectly useful:

abstract class Animal { }  abstract class Pet extends Animal { }  class Dog extends Pet {     public function playFetch() { ... } }  class GermanShepherd extends Dog {     public function beAwesome() { ... } } 

Then, in some specific context, you may not require any object that can do something (interface), but you are specifically looking for a GermanShepherd, because only it can be awesome:

protected function awesomeness(GermanShepherd $dog) {     $dog->beAwesome(); } 

Maybe down the road you'll make a new breed of GermanShepherds that are also awesome, but extend the GermanShepherd class. They'll still work with the awesomeness function, just like with interfaces.

What you certainly should not do is to loop through a bunch of random things, check what they are and make them do their own thing. That's just not very sensible in any context.

like image 123
deceze Avatar answered Oct 14 '22 10:10

deceze