├── Coffee.php ├── README.md ├── Template.php ├── UsersController_with_Interface.php ├── UsersController_without_Interface.php ├── _config.yml └── tea.php /Coffee.php: -------------------------------------------------------------------------------- 1 | addHotWater() 31 | ->addSuger() 32 | ->addCoffee() 33 | ->addMilk(); 34 | } 35 | 36 | } 37 | 38 | $tea = new Coffee(); 39 | $tea->make(); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Welcome to OOP 2 | =================== 3 | 4 | 5 | 6 | Interface 7 | ------------- 8 | 9 | We know that an interface is defined by the interface keyword and all methods are abstract. All methods declared in an interface must be public; this is simply the nature of an interface. Here is the example : 10 | 11 | ```php 12 | logger = $logger; 47 | } 48 | 49 | public function show() 50 | { 51 | $user = 'nahid'; 52 | $this->logger->execute($user); 53 | } 54 | } 55 | 56 | $controller = new UsersController(new LogToFile); 57 | $controller->show(); 58 | ``` 59 | 60 | In the above example I do not use interface. I write to the log using the LogToFile class. But now if I want to write a log using LogToDatabase I have to change hard coded class reference in the above code on line number 23. That line code in below : 61 | 62 | ```php 63 | public function __construct(LogToFile $logger) 64 | ``` 65 | 66 | This code will be 67 | 68 | ```php 69 | public function __construct(LogToDatabase $logger) 70 | ``` 71 | 72 | In a large project, if I have multiple classes and a need to change, then I have to change all the classes manually. But If we use an interface this problem is solved; and we will not need to change code manually. 73 | 74 | 75 | Now see the following code and try to realize what happened if I use interface: 76 | 77 | ```php 78 | logger = $logger; 106 | } 107 | 108 | public function show() 109 | { 110 | $user = 'nahid'; 111 | $this->logger->execute($user); 112 | } 113 | } 114 | 115 | $controller = new UsersController(new LogToDatabase); 116 | $controller->show(); 117 | ``` 118 | 119 | Now If I change from LogToDatabase to LogToFile I do not have to change the constructor method manually. In the constructor method I have Injected an interface; not any arbitrary class. So If you have multiple classes and swap from one class to another class you will get the same result without changing any class references. 120 | 121 | In the above example I write a log using LogToDatabase and now I want to write log using LogToFile, I can call it in this way 122 | 123 | ```php 124 | $controller = new UsersController(new LogToFile); 125 | $controller->show(); 126 | ``` 127 | 128 | I get the result without changing other classes. Because the interface class handles the swapping issue. 129 | 130 | 131 | Abstract class 132 | ------------- 133 | 134 | An abstract class is a class that is only partially implemented by the programmer. It contains at least one abstract method, which is a method without any actual code in it, just the name and the parameters, and that has been marked as “abstract”. 135 | 136 | An abstract method is simply a function definition that serves to tell the programmer that the method must be implemented in a child class. Here is the example : 137 | 138 | ```php 139 | getValue() . "\n"; 148 | } 149 | } 150 | ``` 151 | 152 | Now the question is when will the situation that a method will be needed and must be implemented? Here I will try to explain. Please see the Tea class. 153 | 154 | ```php 155 | addHotWater() 185 | ->addSugar() 186 | ->addTea() 187 | ->addMilk(); 188 | } 189 | } 190 | 191 | $tea = new Tea(); 192 | $tea->make(); 193 | ``` 194 | 195 | Now we look at the coffee class. 196 | 197 | ```php 198 | addHotWater() 229 | ->addSugar() 230 | ->addCoffee() 231 | ->addMilk(); 232 | } 233 | } 234 | 235 | $tea = new Coffee(); 236 | $tea->make(); 237 | ``` 238 | 239 | In the above two classes the three methods addHotWater(), addSugar(), and addMilk() are same. So we should remove duplicated code. We can do it in the following way : 240 | 241 | ```php 242 | abstract class Template 243 | { 244 | public function make() 245 | { 246 | return $this 247 | ->addHotWater() 248 | ->addSugar() 249 | ->addPrimaryToppings() 250 | ->addMilk(); 251 | } 252 | 253 | protected function addHotWater() 254 | { 255 | var_dump('Pour Hot water into cup'); 256 | return $this; 257 | } 258 | 259 | protected function addSugar() 260 | { 261 | var_dump('Add proper amount of sugar'); 262 | return $this; 263 | } 264 | 265 | protected function addMilk() 266 | { 267 | var_dump('Add proper amount of Milk'); 268 | return $this; 269 | } 270 | 271 | protected abstract function addPrimaryToppings(); 272 | } 273 | 274 | class Tea extends Template 275 | { 276 | public function addPrimaryToppings() 277 | { 278 | var_dump('Add proper amount of tea'); 279 | return $this; 280 | } 281 | } 282 | 283 | $tea = new Tea(); 284 | $tea->make(); 285 | 286 | class Coffee extends Template 287 | { 288 | public function addPrimaryToppings() 289 | { 290 | var_dump('Add proper amount of Coffee'); 291 | return $this; 292 | } 293 | } 294 | 295 | $coffee = new Coffee(); 296 | $coffee->make(); 297 | ``` 298 | 299 | I make an abstract class and name it Template. Here I define addHotWater(), addSugar() and addMilk(); and make an abstract method named addPrimaryToppings. 300 | 301 | Now If I make the Tea class extend the Template class then I will get the three defined methods and must define the addPrimaryToppings() method. In a similar way the coffee class will as well. 302 | 303 | I have published this article in the medium. if you’d like to read from the medium blog site, please go to this [link](https://medium.com/@NahidulHasan/understanding-use-of-interface-and-abstract-class-9a82f5f15837) 304 | 305 | Thanks for reading. 306 | -------------------------------------------------------------------------------- /Template.php: -------------------------------------------------------------------------------- 1 | addHotWater() 8 | ->addSuger() 9 | ->addPrimaryToppings() 10 | ->addMilk(); 11 | } 12 | 13 | protected function addHotWater() 14 | { 15 | var_dump('Pour Hot water into cup'); 16 | return $this; 17 | } 18 | 19 | protected function addSuger() 20 | { 21 | var_dump('Add proper amount of suger'); 22 | return $this; 23 | } 24 | 25 | protected function addMilk() 26 | { 27 | var_dump('Add proper amount of Milk'); 28 | return $this; 29 | } 30 | 31 | protected abstract function addPrimaryToppings(); 32 | } 33 | 34 | class Tea extends Template 35 | { 36 | public function addPrimaryToppings() 37 | { 38 | var_dump('Add proper amount of tea'); 39 | return $this; 40 | } 41 | } 42 | 43 | $tea = new Tea(); 44 | $tea->make(); 45 | 46 | 47 | class Coffee extends Template 48 | { 49 | public function addPrimaryToppings() 50 | { 51 | var_dump('Add proper amount of Coffee'); 52 | return $this; 53 | } 54 | } 55 | 56 | 57 | $coffee = new Coffee(); 58 | $coffee->make(); 59 | -------------------------------------------------------------------------------- /UsersController_with_Interface.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 26 | } 27 | 28 | public function show() 29 | { 30 | $user = 'nahid'; 31 | $this->logger->execute($user); 32 | } 33 | } 34 | 35 | $controller = new UsersController(new LogToDatabase); 36 | $controller->show(); 37 | -------------------------------------------------------------------------------- /UsersController_without_Interface.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 26 | } 27 | 28 | public function show() 29 | { 30 | $user = 'nahid'; 31 | $this->logger->execute($user); 32 | } 33 | } 34 | 35 | $controller = new UsersController(new LogToFile); 36 | $controller->show(); 37 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /tea.php: -------------------------------------------------------------------------------- 1 | addHotWater() 31 | ->addSuger() 32 | ->addTea() 33 | ->addMilk(); 34 | } 35 | 36 | } 37 | 38 | $tea = new Tea(); 39 | $tea->make(); --------------------------------------------------------------------------------