blog posts

What is Abstract Programming ?

In the world of programming, the most standard codes are those that have the least code duplication. But there are times when we have to write the same code repeatedly to do almost the same thing with small changes. In this situation, we must look for solutions that minimize these repetitions. To combat these repetitions, we use abstract classes and methods.

What is abstract?

Consider the production line of a donut factory. Donuts are cooked in the same way. After that, a suitable coating sauce with different colors and flavors such as colored cream, chocolate, colored tablets, and. It is poured on them. Depending on the type of sauce that is poured on them, they are packed. You can see that all donuts, regardless of their taste or shape, have the same cooking method. The wrong way is to create a separate production line for each donut color. Does this make sense? Another method is to have the production line shared until the cooking stage. The donuts are then sorted separately at the end of the sauce pouring stage and packed at the end. The following code shows the separate chocolate donut production line in the ChocolateDonut class:

class  ChocolateDonut  {
     public  function  make () {
         return  $ this
            -> makeDough ()
            -> moldDonut ()
            -> fryDonut ()
            -> addChocolate ()
            -> packChocolateDonut ();
    }
    protected  function  makeDough () {
         print  "make donut dough, first." ;
        return  $ this ;
    }
    protected  function  moldDonut () {
         print  "then, mold donut to have a wheel shape." ;
        return  $ this ;
    }
    protected  function  fryDonut () {
         print  "fry the donut carefully." ;
        return  $ this ;
    }
    protected  function  addChocolate () {
         print  "Add enough chocolate on the donut!" ;
        return  $ this ;
    }
    protected  function  packChocolateDonut () {
         print  "Pack donut with brown Packing!" ;
        return  $ this ;
    }
}
$ chocolateDonut = new ChocolateDonut ();
$ chocolateDonut -> make ();

The same steps are repeated to prepare donuts with strawberry sauce:

class  StrawberryDonut  {
     public  function  make () {
         return  $ this
            -> makeDough ()
            -> moldDonut ()
            -> fryDonut ()
            -> addStrawberrySauce ()
            -> packStrawberryDonut ();
    }
    protected  function  makeDough () {
         print  "make donut dough, first." ;
        return  $ this ;
    }
    protected  function  moldDonut () {
         print  "then, mold donut to have a wheel shape." ;
        return  $ this ;
    }
    protected  function  fryDonut () {
         print  "fry the donut carefully." ;
        return  $ this ;
    }
    protected  function  addStrawberrySauce () {
         print  "Add enough strawberry on the donut!" ;
        return  $ this ;
    }
    protected  function  packStrawberryDonut () {
         print  "Pack donut with pink Packing!" ;
        return  $ this ;
    }
}
$ strawberryDonut = new StrawberryDonut ();
$ strawberryDonut -> make ();

But we said that there is no need to repeat the donut preparation codes. Because the process of preparing donuts, except for the decoration part, is conventional and repetitive. So we turn duplicate pieces of code into a contract using the abstract:

abstract  class  DonutTemplate  {
     public  function  make () {
         return  $ this
            -> makeDough ()
            -> moldDonut ()
            -> fryDonut ()
            -> addDressing ()
            -> packDonut ();
    }
    protected  function  makeDough () {
         print  "make donut dough, first." ;
        return  $ this ;
    }
    protected  function  moldDonut () {
         print  "then, mold donut to have a wheel shape." ;
        return  $ this ;
    }
    protected  function  fryDonut () {
         print  "fry the donut carefully." ;
        return  $ this ;
    }
    protected  abstract  function  addDressing () ;
    protected  abstract  function  packDonut () ;
}
class  ChocolateDonut  extends  DonutTemplate  {
     protected  function  addDressing ()
     {
         print  "Add enough chocolate on the donut!" ;
        return  $ this ;
    }
    protected  function  packDonut ()
     {
         print  "Pack donut with brown Packing!" ;
        return  $ this ;
    }
}
class  StrawberryDonut  extends  DonutTemplate  {
     protected  function  addDressing ()
     {
         print  "Add enough strawberry sauce on the donut!" ;
        return  $ this ;
    }
    protected  function  packDonut ()
     {
         print  "Pack donut with pink Packing!" ;
        return  $ this ;
    }
}
$ chocoDonut = new ChocolateDonut ();
$ chocoDonut -> make ();

As you can see in the code, an abstract class is a class that contains at least one abstract method. Abstract methods have no implementation and only force child classes to implement those methods. In the above code, using the keyword extends, we have forced the child class to follow the abstract parent class. If the ChocolateDonut class does not implement the addressing method, the program will encounter an error.

Making new donuts with any decorative sauce is enough to implement a new donut class, an abstract class called DonutTemplate.

Conclusion

In this article, we examined the abstract and how to use it. As you can see, using this method reduces the lines of code and makes it legal and reliable. In teamwork, creating contracts helps the team leader receive integrated codes. One of the main uses of the abstract is when you want to force your team of developers to create several methods, and you prefer their methods to conform to the structures defined by you. Another important point is that a class can implement multiple interfaces but inherit only from one abstract class. Because the interface is just a set of abstract methods, to learn more about the interface, you can read our article about the interface and its application.