My parent class has a few methods that rely on properties that can only be set by the child classes. What's the "best" approach to achieve this?
Also - is it bad OOP that the parent methods rely on something that the child needs to provide?
I'm doing this in PHP, if that matters.
So... You have one class that has an algorithm and another class that is responsible to provide the data for that algorithm... When I word it this way, does it still make sense to you for one of these classes to be a parent of the other?
Your "parent class" should take an object of the "child class" probably as a parameter in a constructor and then use that object to do its work. This compositional pattern is far more reliable, reusable and understandable.
See the Strategy Pattern in the design patterns literature for more information.
In other words, instead of this:
+--------------+
| Parent |
+--------------+
|*getName() |
|showGreeting()|
+-----+--------+
^
|
|
+----+-----+
| Child |
+----------+
|*getName()|
+----------+
Do this:
+--------------------+ +----------+
| Parent | | Child |
+--------------------+ +----------+
|Parent(child: Child)|--->| getName()|
|showGreeting() | +----------+
+--------------------+
The way to handle this in PHP is the same way you handle it in any decent language -- with protected abstract
methods.
http://php.net/manual/en/language.oop5.abstract.php
<?php
abstract class AbstractClass
{
// Our abstract method only needs to define the required arguments
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// Our child class may define optional arguments not in the parent's signature
public function prefixName($name, $separator = ".") {
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
Based on your comment here, it sounds like you're talking about subtyping polymorphism. The basic idea behind polymorphism is that you can do something like this.
Option 1: No default. This should be used if calling this function should never happen from the parent (e.g. Shape) class
class Shape
{
// This doesn't make sense until we know what shape we're talking about
abstract public function getArea();
}
Then you have children classes that look like this:
class Square extends Shape
{
public $sideLength;
public function getArea()
{
return ($this->sideLength ** 2);
}
}
class Triangle extends Shape
{
public $base;
public $height;
public function getArea()
{
return ($this->base * $this->height * 0.5);
}
}
etc.
Option 2: If the function should be able to be called in the parent, you would include the properties and the function itself.
class Rectangle
{
public $length;
public $width;
public function getArea()
{
return ($this->length * $this->width);
}
}
Then you have children classes that look like this:
class Square extends Rectangle
{
public $length;
public function getArea()
{
return ($this->length ** 2);
}
}
etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With