Page 1 of 1

OOP: Polymorphism, Late-Binding, and Method Overloading What they are, and how to use them. Rate Topic: -----

#1 joeyadms  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 41
  • View blog
  • Posts: 178
  • Joined: 04-May 08

Posted 07 June 2008 - 01:32 AM

*
POPULAR

In this tutorial we will look at polymorphism and late-binding in PHP. As well as method overloading. These are commonly used, and pretty powerful. Either way, you , as a PHP programmer, should be aware of these techniques.

PolyMorphism
Definition: polymorphism describes multiple possible states for a single property

What this means is that different instances (childs) of one thing (object) can behave differently while doing the same action (method).

Basically, the commonly used method of explaining this is using the animal analogy. Both Dogs, and Cats are animals, all animals can speak,but when told to speak, they do it differently, a dog may bark, and a cat may meow.

Even more simplified, Polymorphism is just overriding methods from a subclass. Look at the following for an example:
<?php

class animal {
	public $name;
	protected function setName($name){
		$this->name = $name;
	}
	public function speak(){
		return "No Animal Selected!";
	}

}

class dog extends animal {
	public function __construct($name){
		$this->setName($name);
	}
	public function speak(){
		return "Woof Woof";	
	}
}

class cat extends animal {
	public function __construct($name){
		$this->setName($name);
	}
	public function speak(){
		return "I'm In your class, overloading your methods"; // :)
	}
}

class human extends animal {
	public function __construct($name){
		$this->setName($name);
	}
	public function speak(){
		return "Hello, My Name is " . $this->name;
	}
}

$animal = new animal(); // Animal
$dog = new dog('rover'); // Dog named Rover
$cat = new cat('garfield'); // Cat named Garfield
$human = new human('fred'); // Human named Fred

// Non-existent animal cannot speak
echo $animal->speak();

// Dog's bark
echo $dog->speak();

// Cat's do nefarious things
echo $cat->speak();

// Human's Introduce themselves
echo $human->speak();



You can see how each object, although belonging to the animal class, react differently whenever told to do the same function.
You migh ask, well isn't this the same as a regular function, what is the point. The point is that you can override functions in your
base class, while still maintaining a link to that class. So say you have a logging engine, look at the bottom for a better understanding
class logger {
	public function log($error){
		$this->logToFile($error);
	}
	public function logToFile($error){
		// Log info to file
	}
}
class http_error extends logger {
	public function log($error){
		$err = "HTTP - " . $error;
		$this->logToFile($err);
	}
}
class mysql_error extends logger {
	public function log($error){
		$err = "MYSQL - " . $error;
		$this->logToFile($err);
	}
}


Now you see how this can come in handy. Of course this is very simple, just use your imagination on how you can make each
subclass differ from the other, I mean they are their OWN CLASS for sakes. The power is endless, for instance, for httpd errors
you could log relevant info, such as http response code, page error occurred etc.

That is polymorphism in a nutshell.

Late Binding

Everyone was frowing on PHP because of its lack of late-binding, however we now have it. What late-binding is, is refering to
methods and properties in the base class that do not exist yet, but are present in subclasses. In other words, calling
unique methods in children from the parent.

Here is an example:
<?php
interface contact{
	function getSig();
}
class post_office{
	public function send_message($recpt,$message){
		$signature = $this->getSig(); // Get Signature from sender
		// Send Message to Database or Wherever
	}
}
class joey extends post_office implements contact {
	public function getSig(){
		return "Harry Adams \n
			PHP Programmer";
	}
}

$joey = new joey();
$recpt = 'Stuart';
$message = "Did you get the memo about those TPS reports?";
$joey->send_message($recpt,$message);


Lets examine this.

First we create an interface contact. All of our contacts will implement this, to be
sure they have the proper methods to perform the functions in order to send mail.

Now in our parent class, the 'post_office', we send a message, when we do we first grab the signature using the method
$this->getSig();, however there is not a method called that in this class. If you remember, and you should it was a couple lines ago,
we set up our interface so that every contact must have a function to retrieve a signature. So when we send a message from our class joey
it uses the method in that class to grab the signature.

Now, there have been arguments over speed with late binding but that is completely irrelevant. My point, and argument against
using late binding is that there is no fail-safe, if you do not have a method getSig() in child classes, you will have a fatal error,
and you don't want that, you want a seemless application that fails gracefully.

Instead you should have a default method inside your base class, and override it with polymorphism, learned above, to create
that different functionality, see below:
<?php
interface contact{
	function getSig();
}
class post_office{
	public function send_message($recpt,$message){
		$signature = $this->getSig(); // Get Signature from sender
		// Send Message to Database or Wherever
	}
	public function getSig() {
		return "Sender not verified";
	}
}
class joey extends post_office implements contact {
	public function getSig(){
		return "Harry Adams \n
			PHP Programmer";
	}
}

class kyle extends post_office {

}



Now you see, class joey has overridden getSig() in our post_office class.
So whenever we send a message, we will still grab the signature. However if we try to send a message from our kyle
class, it will fail safely, and attatch the default signature from the method in our post_office class.

I do not believe late binding prevails, overriding methods is much safer, however it is good to know, because you never know when you might
need to use it.

Overloading Methods

No. Not overriding, as above, but overloading.

In polymorphism, you have methods that behaves differently depending on who is performing it, method overloading is having one method
that behaves differently depending on the number of arguments passed, or type. Make sense? here is an example:
<?php
class overloading
{
  function __call($method, $args){
	if($method == 'talk'){
		if(count($args) == 0){
		  $this->sayNothing();
		}
		elseif(count($args) == 1){
		  if(is_array($args[0])){
			$this->sayArray($args[0]);
		  }else{
			$this->saySentence($args[0]);
		  }
		}
		elseif(count($args) == 2){
		  $this->sayTwo($args[0], $args[1]);
		}
		else{
		  return false;
		}
	}
  }
  function rawr() {
	echo "rawr";
  }
  function sayArray($arr){
	foreach($arr as $s){
		$this->saySentence($s .". ");
	}
  }
  function sayNothing(){
	echo "I have nothing to say.";
  }

  function saySentence($sentence){
	echo $sentence;
  }

  function sayTwo($first,$second){
	echo $first . ".<br/>" . $second . ".";
  }
}

$o = new overloading();
$o->rawr();
$o->talk('a sentence');
$o->talk('a sentence','another sentence');
$o->talk(array('hello I am joey.','nice to meet you'));



I'll make this fast, if you look at the magic method __call, when a method is called, first it is parsed through your
function with provide method name, and arguments. You can modify what you want to happen depending on what is passed and what is called,
you can also do this with properties with __get and __set , look at php.net for more info on those.

I have never had a need for overloading, but I do see the power in them and will use them in the near future when making some modules and snippets probably.

Well there you have it, some things about OOP in PHP you may have not known, I hope this helps you out.

Is This A Good Question/Topic? 7
  • +

Replies To: OOP: Polymorphism, Late-Binding, and Method Overloading

#2 Baljit  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 30-May 10

Posted 30 May 2010 - 11:51 PM

i read all that tutorial, it is realy easy to understanding,
i have got usefull information from this, Thanks dreamincode.net for this, and now i am member this site

This post has been edited by Baljit: 31 May 2010 - 12:54 AM

Was This Post Helpful? 0
  • +
  • -

#3 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3541
  • View blog
  • Posts: 10,251
  • Joined: 08-June 10

Posted 16 August 2010 - 07:14 AM

some comments to Late Static Binding:

I know of 3 possibilities to ensure that a parent class’s method can use a yet unknown child class method.

  • the already mentioned default method approach.

  • declaring an abstract method in the parent. this requires the parent class to be declared abstract (cannot be instantiated) as well as the abstract method declaration.
    abstract class post_office
    {
    	public function send_message($recpt,$message){
    		$signature = $this->getSig(); // Get Signature from sender
    		// Send Message to Database or Wherever
    	}
    
    	abstract public function getSig();
    }
    class joey extends post_office 
    {
    	public function getSig(){
    		return "Harry Adams \n
    			PHP Programmer";
    	}
    }
    
    

  • implementing the interface in the parent class and not defining/declaring the method. the parent class must also be declared abstract, since it misses a required method.
    interface contact
    {
    	function getSig();
    }
    abstract class post_office implements contact
    {
    	public function send_message($recpt,$message){
    		$signature = $this->getSig(); // Get Signature from sender
    		// Send Message to Database or Wherever
    	}
    }
    class joey extends post_office 
    {
    	public function getSig(){
    		return "Harry Adams \n
    			PHP Programmer";
    	}
    }
    
    

Was This Post Helpful? 0
  • +
  • -

#4 nightscream  Icon User is offline

  • D.I.C Head

Reputation: 19
  • View blog
  • Posts: 237
  • Joined: 04-December 08

Posted 25 August 2010 - 04:49 PM

Dormilich is right, you should have declared post_office abstract, it will not be possible to make an object of post_office but you can use joey. This makes it possible to define functions that are the same for all sub classes and make sure all functions that have no meaning in post_office are declared in joey or kyle..
Was This Post Helpful? 0
  • +
  • -

#5 AdaHacker  Icon User is offline

  • Resident Curmudgeon

Reputation: 452
  • View blog
  • Posts: 811
  • Joined: 17-June 08

Posted 28 August 2010 - 08:25 AM

View Postjoeyadms, on 07 June 2008 - 02:32 AM, said:

What late-binding is, is refering to
methods and properties in the base class that do not exist yet, but are present in subclasses. In other words, calling
unique methods in children from the parent.

Actually, that's incorrect. What you're describing here is not late binding, but simply a design error.

In both examples, you have the child class inheriting send_message() and implementing contact. However, you have send_message() depending on the contact interface, which post_office does not implement. That's just a misunderstanding of basic object-oriented design. You can't depend on an interface you don't implement - that's the entire point of interfaces!

The correct design would be to either have post_office implement contact with an abstract getSig()or to make send_message() an abstract method and let the child implement it. You just can't take a dependency on the interface in the parent class and only implement it in the child class - the inheritance chain only goes one direction. PHP might not complain about this, but it's still incorrect.

As for late binding, also called dynamic binding, that's something else entirely. It refers to binding a type to a variable at run-time rather than compile-time. This is mostly relevant in over-riding methods in a parent class. For example:
class Fizz {
   public function foo() {
      echo "Fizz";
   }

   public function bar() {
      $this->foo();
   }
}

class Buzz extends Fizz {
   public function foo() {
      echo "Buzz";
   }
}

$x = $_GET['fizz'] ? new Fizz() : new Buzz();
$x->bar();


In this case, if $x is a Fizz, then $x->bar() will print "Fizz", and if it's a Buzz, it will print "Buzz". This is an example of dynamic binding because the type of $x is determined at run-time. The interpreter detects if $x is an instance of the child class and overrides the appropriate method.

If the binding were static, it wouldn't work that way. The compiler would see that Fizz::bar() calls $this->foo() and bind $this to type Fizz, so that if $x were a Buzz, the overridden method would not be called. This is the same behavior we see in PHP 5.2 and earlier with the late static binding "bug". (In quotes because I consider it a bug, even though it's actually designed to work that way.)
Was This Post Helpful? 3
  • +
  • -

Page 1 of 1