Polymorphism in PHP

While thinking about a programming language deficiency, I rediscovered polymorphism. Overloading a function allows a function call to behave differently when passed variables of different type. I was trying to devise a method of simulating function overloading, because PHP does not support it. I considered implementing a function with an if-else statement ladder that tests the type of the actual argument and executes statements that correspond to the argument’s type. This technique may ultimately result in a monolithic function or a function implementation that is too knowledgeable of multiple class hierarchies. Rethinking a problem that I was hoping to solve with function overloading allowed me to accept the lack of this language feature and think of other techniques.

There are two problems that arise from the if-else statement ladder approach. The implementation of such a function would require the function to have knowledge of every data type to be used with it. This problem can be extended to knowing class hierarchies, if subclassing is involved. This means that an introduction of a new data type to be processed by the function would require the function to be modified, which creates the possibility that the modification will break other existing code that relies on the function. The second problem is having the function’s maintainer think about how the function should operate on the different data types that can be passed to it. This responsibility is better placed on the people who maintain the different data types.

One solution that deals with the problems in the if-else statement ladder is polymorphism. Polymorphism allows a set of heterogeneous elements to be treated identically. It is achieved through inheritance. In PHP, interface inheritance and implementation inheritance can be written explicitly through the use of interfaces and class extensions, respectively. Interfaces specify a class interface without providing an implementation. Classes from different class hierarchies can implement an interface, and in this way, it can be seen as different from abstract classes. When a class is defined to implement an interface, the language enforces a rule that the class implements all features of the interface. A method that operates on an interface will accept an object of any class that implements the interface, and it will function correctly.

Here is a toy example of interface inheritance, polymorphism, and PHP type hinting:

<?
	interface HasArea
	{
		public function area();
		public function areaUnit();
	}
	
	abstract class Shape
	{
		private $color;
		
		public function __construct( $color )
		{
			$this->color = $color;
		}
		
		public function getColor()
		{
			return $this->color;
		}
	}
	
	class Rectangle extends Shape implements HasArea
	{
		private $w;
		private $h;
	
		public function __construct( $color, $w, $h )
		{
			parent::__construct($color);
			$this->w = $w;
			$this->h = $h;
		}
	
		public function area()
		{
			return ($this->w * $this->h);
		}
		
		public function areaUnit()
		{

			if( $this->area() > 1 )
				return "square meters";
			else
				return "square meter";
		}
	}
	
	class Territory implements HasArea
	{
		private $name;
	
		public function __construct( $name )
		{
			$this->name = $name;
			/* not used in this example... */
		}
	
		public function area()
		{
			return 5;
		}
		
		public function areaUnit()
		{
			return "cities";
		}
	}
	
	function outputArea( HasArea $ha )
	{
		echo "The area is:  "
		 . " {$ha->area()} {$ha->areaUnit()}\n";
	}
	
	$HAs = array(
		new Rectangle("red",2,3),
		new Territory( "somename" )
	);

	foreach( $HAs as $HA )
	{
		outputArea( $HA );
	}
?>

Type hints help the PHP interpreter enforce the restriction that outputArea() operates only on objects of data types that implement the HasArea interface. Rectangle and Territory are from unrelated class hierarchies. outputArea() can operate on these classes, since these classes implement the HasArea interface.

The explored method accomplishes only some of the features offered by function overloading. In the above example, outputArea() was restricted to one argument. In some programming languages, a function can be overloaded on the number of arguments along with the types of those arguments and the order that those types appear in the argument list. This method, however, was useful in a problem I considered solving with function overloading.

18 Responses to “Polymorphism in PHP”

  1. Anonymous Says:

    short and good

  2. Gachl Says:

    thanks! I needed that!

  3. sanjay Says:

    very good

  4. Energy Recruitment Says:

    Nice example;
    Can you contact me on energy.recruitment@gmail.com because i am learning php 5 oop.
    waiting for your kind reply

  5. grant Says:

    I think there is in error in the Territory class. Where does $r come from?
    It would be great to have a nice example like this showing the essential difference between an abstract class and an interface.

  6. redefine Says:

    nice pseudo polymorphism, as I know PHP does not support native polymorphism but of course you can do it this way which actually does quite the same as you would expect from polymorphic array!

  7. Steve Says:

    To grant:

    Thanks. It looks like $r in the constructor is an undefined variable. Fixed by substituting $r with $name and introducing an argument to the constructor.

  8. Satya Says:

    Nice Article!!!!!

  9. Tsr Says:

    Its very useful….i am a beginner it will help me to improve myself thank you

  10. Tsr Says:

    I need your help to develope my knowledge in oops concepts……

  11. Aneesh Says:

    Nice and Cool demo thanks

  12. amal Says:

    i am satisfied with this site, please remove some useless comments..
    System level decoding is poor….but i studied a lot

  13. PHP Offshore India Says:

    Thansk I understood that polymorphism is the process of creating several objects from specific base classes

  14. Iqbal Husain Says:

    Very good example cleared some oops concepts..

  15. Yogesh Says:

    Nice Example …………….!

  16. Michael Kubler Says:

    I’ve found that if you need to give more than 2 variables to a function then it’s usually better to enter them as an array.

  17. daGrevis Says:

    Nice explanation! Very similar to Java’s polymorphism.

  18. abdul Says:

    and now you have to add access functions for each required data type? so this would be a solution to what exactly? it def. not simulating the polymorphism mate…

Leave a Reply