Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OOP - where to declare properties?

Tags:

oop

php

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?

  1. Parent class has the properties set to defaults (e.g. a string is set to null string), then child class sets parent's properties in its constructor.
  2. The child class defines the properties as its own
  3. Should the parent class' methods accept the necessary values as parameters, instead?
  4. Something else???

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.

like image 271
StackOverflowNewbie Avatar asked Jun 23 '17 15:06

StackOverflowNewbie


3 Answers

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()      |    +----------+
+--------------------+    
like image 73
Daniel T. Avatar answered Sep 21 '22 00:09

Daniel T.


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";
?>
like image 41
Bryan Boettcher Avatar answered Sep 19 '22 00:09

Bryan Boettcher


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.
like image 29
Mike Avatar answered Sep 21 '22 00:09

Mike