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.







MultiQuote





|