Reputation: 9
I have read several of the threads regarding abstract classes in PHP, and none of the answers seem to address my question: Why are the methods in an abstract class required to have the same signature (same arguments) as the child classes when it is impossible to know what might be required for the child class implementations of those abstract methods? The classic example of the abstract class is something like class GeometricShape(), and two of the child classes might be class Rectangle extends GeometricShape() and class Circle extends GeometricShape(). The getArea() method for one needs the length and width as arguments and the other needs just the radius. How is that supposed to work in PHP?
Upvotes: 0
Views: 674
Reputation: 14470
I think you are mixing OOP various concepts
Abstraction comes into play when your class has to provide a conceptual limitation for a class and its subclasses. e.g take an example from real world, Tree
is conceptual thing until its materialized into sth physical e.g Apple Tree
. If you are naturalist , you would like to keep the natural thing natural (don't like genetic modifications !) and make certain that Apple Tree
does yield apples not mangoes and does have roots
. Now focus on the terms roots
,fruit
w.r.t Tree
and w.r.t Apple Tree
and any other Xyz Tree
. When we discuss these with respect to Tree
they are very open end interface every tree should have or MUST have to be called a Tree
( unless or until its GM one). roots
interface in Tree
is abstract interface bcz subclass i.e Apple Tree
know how to suck minerals from ground to make apple fruit
. So every plant take different approach to implement the roots
interface.
In your example getArea() method more or less a example of method overriding ,where a child decides to ignore/suppress some part of its inherited behavior/attributes.
I hope this natural example is not that complex
Upvotes: 0
Reputation: 780673
length
, width
, and radius
shouldn't be arguments to the methods, they should be properties in the classes. When you want to get the area of an object, you just call:
$area = $shape->getArea();
The Rectangle
method will return length*width
, the Circle
method will return pi*radius*radius
.
The signatures have to be the same because this code doesn't know whether it's operating on a Circle
or Rectangle
, it needs to treat all GeometricShape
objects equivalently.
Upvotes: 2
Reputation: 37029
This is a good and interesting question. In a case like GeometricShape(), GetArea would be without arguments. A better example would be an abstract method called FillColor that takes the color as an argument like so:
abstract class GeometricShape
{
abstract function GetArea();
abstract function FillColor($color);
}
class Square extends GeometricShape
{
function GetArea()
{
echo "Square - get area\r\n";
}
function FillColor($color)
{
echo "Square - Filling color $color\r\n";
}
}
class Circle extends GeometricShape
{
function GetArea()
{
echo "Circle - get area\r\n";
}
function FillColor($color)
{
echo "Circle - Filling color $color\r\n";
}
}
$square = new Square();
$square->FillColor('green');
$circle = new Circle();
$circle->FillColor('red');
Abstract class is to provide a common personality to the children that children may override. Abstract classes can provide scaffolding/basic properties also that children can use as is.
In case an abstract method is supposed to provide a signature that is more lenient, an array can be sent to it. That way, circle can override the method with an array containing radius whereas rectangle can send an array with length and width. The method body will use the array to determine what has been received and what to do with it.
Upvotes: 1