...

View Full Version : PHP Polymorphism



phantom007
03-12-2009, 09:28 AM
Hello People,



Can someone please give me an example of Polymorphism in PHP with a short code?



Thanx

Fou-Lu
03-12-2009, 09:31 AM
abstract class Shape
{
public abstract function calculateArea();
}

class Rectangle extends Shape
{
public function calculateArea()
{
return $this->x * $this->y;
}
}

class Circle extends Shape
{
public function calculateArea()
{
return $this->r * $this->r * 3.14;
}
}


That help?


I should note that in PHP the polymorphism isn't quite the way it should be. I mean that it does work, but since we have a weak datatype, its not correct. In java or C#, the above could work like so:


Shape circle = new Circle(5);
Shape square = new Rectangle(5, 5);

circle.calculateArea();
square.calculateArea();

While it still works in PHP, the idea is that circle and square are types of Shape, while in PHP there is no such way to declare this (except in typehinting for you're methods).

phantom007
03-12-2009, 09:47 AM
Hi

I am sure it will help if you can plz explain me what is happening and also why are you using an abstract class in a polymorphism example?


Thanx

abduraooft
03-12-2009, 09:51 AM
I am sure it will help if you can plz explain me what is happening and also why are you using an abstract class in a polymorphism example?
Fou-Lu had given a nice explanation for what's an abstract class (http://www.codingforums.com/showthread.php?t=145943)

oesxyl
03-13-2009, 09:25 AM
abstract class Shape
{
public abstract function calculateArea();
}

class Rectangle extends Shape
{
public function calculateArea()
{
return $this->x * $this->y;
}
}

class Circle extends Shape
{
public function calculateArea()
{
return $this->r * $this->r * 3.14;
}
}


That help?


I should note that in PHP the polymorphism isn't quite the way it should be. I mean that it does work, but since we have a weak datatype, its not correct. In java or C#, the above could work like so:


Shape circle = new Circle(5);
Shape square = new Rectangle(5, 5);

circle.calculateArea();
square.calculateArea();

While it still works in PHP, the idea is that circle and square are types of Shape, while in PHP there is no such way to declare this (except in typehinting for you're methods).

I'm not sure, but I guess this is huppend because constructor and destructor are not inherited by default. I don't have much time to spare, but I'm curios, if this is happend if you write your own constructor for each extended class.

best regards

Fou-Lu
03-13-2009, 09:45 AM
I'm not sure, but I guess this is huppend because constructor and destructor are not inherited by default. I don't have much time to spare, but I'm curios, if this is happend if you write your own constructor for each extended class.

best regards

I'm not quite sure that I'm following you? The constructor / destructor is inherited in PHP (with a valid scope of course), though if you override them in child classes you have to explicitly call the parent constructor (this is something I do not like, I wish it would at least force the parent call). I guess thats probably due to the lack of overloading capability in PHP.
I'm thinking that you're looking at the edit part of the code. I'm not too worried about the constructor definitions on those, but the important part was the storing the Circle and Rectangle object's as shapes. In PHP, we don't have that luxury (which is what I mean by we don't really have polymorphism, since we don't really bind an inherited method to a Shape).


$circle = new Circle(5);
$rect = new Rectangle(5, 5);

While in PHP these are extensions of Shape so can be validated against $circle instanceof Shape;, they are actually a Circle and Rectangle object, not a shape object (unlike the C#/Java ones shown earlier). However, this will work:


function getArea(Shape $shape)
{
return $shape->getArea();
}

$area = getArea($circle);

which is a simple example of the typehinting. Thats about the extent of the polymorphism in PHP.

Does that sorta clear up what I was trying to show? So yeah, we have polymorphism, but it doesn't appear to be 'real' polymorphism.

oesxyl
03-13-2009, 10:58 AM
maybe I don't understand what you mean by real pholimorphism. I see what you say more as week vs. strong type future/limitation of the language.
As far as you can't declare a given type for a variable like Shape $rect, it must at first look to be of type of the constructor. Latter if you want to check for inheritance, to be sure that you have a common base class, you have another mechanism to do that. For example:


class SpecialRectangle extends Rectangle {}

$spec = new SpecialRectangle(3.0,4.0);
echo get_class($spec);
echo get_parent_class($spec);
echo get_parent_class(get_parent_class($spec));

or you can use is_subclass_of(instance, classname) for checking.

PS: you are right about constructor/destructor inheritance. I missunderstand what you said, wrong in what I said and also I'm not sure I understand you this time, :)

best regards

Fou-Lu
03-13-2009, 11:42 AM
We're on the same point, but looking at it from different sides. It really is just PHP's datatype weakness.
Lets see if I can do up a better example of what I mean:


public class Circle extends Shape
{
public double getPerimiter()
{
return 2 * this.r * Math.PI;
}
}

// Some main:
Shape c = new Circle(5); // Memory would list this as typeof Shape
c.getPerimiter(); // Illegal, no signatured getPerimiter in Shape
((Circle)c).getPerimeter(); // Legal, c is now a Circle




class Circle extends Shape
{
public function getPerimiter()
{
return 2 * $this->r * M_PI;
}
}

$c = new Circle(5); // Memory lists this as typeof Circle
$c->getPerimiter(); // Legal, since $c is a Circle, not a Shape


So I guess what I mean as 'real' polymorphism is how its existing in memory. Strong datatype language (C#, Java, C++, etc) would indicate in memory that this 'Circle' is a 'Shape', while in PHP since it is weak has no way in memory to define it as anything but a 'Circle'. Even with the typehinting, it doesn't constraint the availability of non-existant function calls. So, if you typehinted the Shape class in a function, you can still call the getPerimiter on the shape (even though you shouldn't be able to), and if you passed it a Square instead of a Circle, it would toss a fatal error.

oesxyl
03-13-2009, 12:45 PM
I think I get it now, :)
yes it's true what you say. I think is more a problem of habits about what level of checking you expect from a language. Take for example javascript, where language is a mushup of oop and functional futures. If you try to implement same level of checking like in a c++-like language, I'm sure you lose a lot of future of the language.

best regards

Fou-Lu
03-13-2009, 01:05 PM
Exactly, thats a good way of putting it. And with that, you can see we were indeed talking about the same thing (just looking at it from different perspectives). Its all about the expectations ;D



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum