Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: what is the use case of abstract class

Tags:

php

As per php.net documentation :

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private. Furthermore the signatures of the methods must match, i.e. the type hints and the number of required arguments must be the same. For example, if the child class defines an optional argument, where the abstract method's signature does not, there is no conflict in the signature. This also applies to constructors as of PHP 5.4. Before 5.4 constructor signatures could differ.

In php.net they have shown the following example:

abstract class AbstractClass
{
    // Force Extending class to define this method
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // Common method
    public function printOut() {
        print $this->getValue() . "\n";
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}

class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";

$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";

If I run this I get the below output:

ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2

Reading the documentation, my initial understanding was "parent classes in general can not access methods from their children if they are extend" and that's why we need abstract classes. However, when I tried the same example above with a little bit of tweak, removing all the abstractions (given below) I see the exact same output as the previous example. Therefore, why do we need abstract classes in PHP. Only use case I found is while implementing an interface in the parent class; I get error if I do not declare the parent as abstract. Is there other cases where I must or it is highly recommended to use abstract class?

//abstract
class AbstractClass
{
    // Force Extending class to define this method
    //abstract protected function getValue();
    //abstract protected function prefixValue($prefix);

    // Common method
    public function printOut() {
        print $this->getValue() . "\n";
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}

class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";

$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
like image 530
Kamrul Khan Avatar asked Mar 15 '23 18:03

Kamrul Khan


1 Answers

If I have a group of similar things, let's say furniture.

class Chair extends Furniture {
    // define methods to handle being sat on
}
class Table extends Furniture {
    // define methods to handle holding things up
}

And so on. But "Furniture" is an abstract concept. It is not, itself, a thing the way "Chair" and "Table" are. Therefore, it would be best to define:

abstract class Furniture {
    // define methods that apply to all kinds of furniture
}

It's always a good idea to think of classes as "types of thing". Some are concrete, like chairs and tables, and others are abstract, like furniture.

The point is, it makes no sense to have new Furniture() in your code, because furniture should be a specific kind. Using abstract class disallows new Furniture() and acts as a sanity check.

like image 73
Niet the Dark Absol Avatar answered Mar 23 '23 14:03

Niet the Dark Absol