Abstract class hide the implementation and group of similar type data.
Group of data is understandable but implementation hiding is not.
According to the following code:
abstract class area
{
protected $a;
protected $b;
abstract public function CalculateArea($ax, $ay);
}
class rectangle extends area
{
public function CalculateArea($ax, $ay)
{
$this->a = $ax;
$this->b = $ay;
return $this->a * $this->b;
}
}
class ellipse extends area
{
private $c = 3.1416;
public function CalculateArea($ax, $ay)
{
$this->a = $ax;
$this->b = $ay;
return $this->a * $this->b * $this->c;
}
}
$RectangleArea = new rectangle();
echo $RectangleArea->CalculateArea(2, 3);
echo"<br>\n";
$EllipseArea = new ellipse();
echo $EllipseArea->CalculateArea(2, 3);
Here a
,b
properties in abstract class area
that is used to next inherited class rectangle
and ellipse
. Through this it is understandable that grouping of data satisfied but how the implementation hiding is satisfied? Can anyone clarify it?
Thanks in advance.
CodePudding user response:
In your abstract class $a and $b are protected.
abstract class area{
protected $a;
protected $b;
abstract public function CalculateArea($ax,$ay);
}
This is how visibility works:
public to make property/method available from anywhere, other classes and instances of the object.
private when you want your property/method to be visible in its own class only.
protected when you want to make your property/method visible in all classes that extend the current class including the parent class.
If you don't use any visibility modifier, the property/method will be public.
see this for reference https://stackoverflow.com/a/4361582/9354303
CodePudding user response:
What's presented is an interface, because the actual logic is pushed down into the implementing class, which doesn't, in fact, create a hidden implementation.
Here's a modified example demonstrating something closer to what you're describing, because you access through area()
but the implementation is private to the abstract class.
trait CalculatesArea
{
private $pi = 3.1416;
private function rectangularArea(): float
{
return $this->a * $this->b;
}
private function ellipticArea(): float
{
return $this->a * $this->b * $this->pi;
}
}
abstract class Shape
{
use CalculatesArea;
public function __construct(protected float $a, protected float $b) {}
public function area(): ?float
{
if ($this instanceof Rectangle) {
return $this->rectangularArea();
}
if ($this instanceof Ellipse) {
return $this->ellipticArea();
}
return null;
}
}
At this point, we have an abstract class that utilizes a trait and determines, based on checking it's final implementation, which area method to use.
Now we just extend it and each uses a common ->area()
invocation to call into the abstract class:
class Rectangle extends Shape {}
class Ellipse extends Shape {}
var_dump(
(new Rectangle(3, 4))->area(),
(new Ellipse(1.3, 3.8))->area(),
);
Because the trait has the calculate methods as private, they are "hidden" (private method) from the implementing class (protected method), as well as any external code (public method).