S
S
Stanislav2016-06-08 19:26:23
PHP
Stanislav, 2016-06-08 19:26:23

What are abstract classes used for?

Here's a code template that everyone tries to explain the usefulness of abstract classes with:

abstract class ClassName
{
    abstract public function doSomething($something);
//не абстрактные методы
}

class ChildClass extends ClassName
{
    public function doSomething($something)
    {
        //code
    }
}

So, what is the point of using such a construction, if you can do it like this:
class ClassName
{

//не абстрактные методы
}

class ChildClass extends ClassName
{
    public function doSomething($something)
    {
        //code
    }
}

What is it for? And in what examples? In Google, all examples are similar to what I threw off from above, i.e. meaningless.
So far, the only thing that comes to mind is to give an understanding to another programmer that it is necessary to use inheritance with such and such methods.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
D
D', 2016-06-08
@Stasgar

1) You cannot instantiate an abstract class.
2) Methods declared as "abstract" are required to be implemented. That gives confidence that any successor will implement these methods.
3) Having opened a file with an abstract class, I immediately see the methods that it has, and which I need to implement. In your example, I don't know which methods relate specifically to ChildClass and which to ClassName.
All these interfaces, abstract classes, etc., are needed when several (many) people are working on the project, and the project is a little more than "your own mega-cool blog".

X
xfg, 2016-06-08
@xfg

Try to thoroughly understand what polymorphism is, especially one of its varieties - type polymorphism.
Type polymorphism is often used in php. Here is its essence on your example:

abstract class ClassName
{
    abstract public function doSomething($something);
//не абстрактные методы
}

class ChildClass extends ClassName
{
    public function doSomething($something)
    {
        //code
    }
}

class Main {
  public run(ClassName $class) {
    //code
  }
}

$obj = new Main();
$obj->run(new ChildClass());

The method in Main::run() is parameterized, its $class parameter can now only match child classes of your abstract class ClassName.
Why is this needed?
This is needed when you may have multiple implementations of the same component. And you know for sure that in the future you may need a different implementation. For example, imagine a caching class. Agree that you can cache to a file, you can cache it in a database, you can cache it in memory, etc. In this case, you can isolate the Cache abstraction with common functionality for any implementation and create descendants of CacheFile, CacheMysql, CacheRedis, etc.
Now when you need a cache component, you can inject it through a method parameter that is parameterized with the Cache type, if you give something else to this method, the interpreter will throw an exception. You get flexibility. At any time, you can replace the implementation of the cache component with a different one by simply passing a different child object of the Cache abstract class to the method. You already know exactly what its contract should be, and you know for sure that you don't need to fix the method that your Cache class uses. Well done, you just applied the polymorphic open/closed principle , one of the SOLID principles , which means that your code has become a little better.
But, most likely, if you have not heard anything about this, then you should definitely get acquainted with the Dependency injection container, which will automatically inject the required component, instead of you. You will only specify in the configs which implementation of the component you need to submit to the rest of the code. Then your entire project will be able to move from CacheFile to CacheRedis and vice versa by changing just one line in the config.
Also, if the component does not have a common implementation that can be put into an abstract class, then instead of it, you should use an interface. The idea remains. Polymorphically override different implementations.
In addition to examples in Google, see also the live code of open source projects.
https://github.com/yiisoft/yii2/blob/master/framew...
https://github.com/yiisoft/yii2/blob/master/framew...
https://github.com/yiisoft/yii2/blob/master/framew...
etc.

#
#algooptimize #bottize, 2016-06-08
@user004

Encapsulation, polymorphism, etc.
I don't remember the exact terms.
You can work with different objects in the same way if you see only the base class in them.

A
Andrey, 2016-06-08
@VladimirAndreev

Here you write database drivers.
accordingly, you must have an abstract driver class. which forces descendants to implement a certain set of methods, in turn, for some operations, it can offer some kind of implementation.
and then, you have, let's say, a model that needs a database driver to be passed to it.
if you have an abstract class - you can write like this: function __construct(Db_Driver $driver);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question