Object Oriented PHP with Keywords Interface, Extends, Implements

Over the past few months, I have come a long way in teaching clean oop, and now I am applying design templates to my work! Therefore, I had to expand my knowledge of php, and I use interfaces, expanding them, and then implementing classes for these interfaces. My question is to build a class from an interface that extends another, take this code, for example:

interface Car { function doGeneralCarStuff(); vinNumber =; } interface CompactCar extends Car { static $numCompactCars; function doCompactCarStuff(); } class HondaCivic implements CompactCar { function doGeneralCarStuff() { //honk horn , blink blinkers, wipers on, yadda yadda } function doCompactCarStuff() { //foo and bar and foobar } } class ToyotaCorolla implements CompactCar { function doGeneralCarStuff() { //honk horn , blink blinkers, wipers on, yadda yadda } function doCompactCarStuff() { //foo and bar and foobar } } myCar = new HondaCivic(); myFriendCar = new ToyotaCorolla(); 

Ok, now Iโ€™ll say that I want to learn something about one of the interfaces from which my Honda extends, i.e. CompactCar interface. I want to know how many compact cars ($ numCompactCars) have been created. I am new to deep (deep to me: p) OOP, so please provide guidance if I do not do it right. Thank you very much!

+4
source share
3 answers

if you save your โ€œnew carsโ€ in an array, you can easily skip them and check if this interface implements. Sort of:

 $cars['myCar'] = new HondaCivic(); $cars['myFriendCar'] = new ToyotaCorolla(); $compact_counter = 0; foreach ($cars as $car) if ($car instanceof CompactCar) $compact_counter ++; 

$compact_counter will show how many compact cars have been sold.

+2
source

The only drawback with the Factory pattern is that you can get around it anytime - i.e. new HondaCivic() will break the number of cars.

Here's something more reliable:

 <?php interface Car { function doGeneralCarStuff(); } // Declare as abstract so it can't be instantiated directly abstract class CompactCar { // Increment car count function __construct() { CompactCar::$numCompactCars++; } function __clone() { CompactCar::$numCompactCars++; } // Decrement car count function __destruct() { CompactCar::$numCompactCars--; } // Prevent external modification of car count protected static $numCompactCars; // Get the current car count static public function getCount() { return CompactCar::$numCompactCars; } // Require a compact car function for descendant classes abstract public function doCompactCarStuff(); } // Extend and implement class HondaCivic extends CompactCar implements Car { function doGeneralCarStuff() { } function doCompactCarStuff() { } } // Extend and implement class ToyotaCorolla extends CompactCar implements Car { function doGeneralCarStuff() { } function doCompactCarStuff() { } } $myCar = new HondaCivic(); // 1 car $myFriendCar = new ToyotaCorolla(); // 2 cars printf("Number of compact cars: %d\n", CompactCar::getCount()); $myCar = new HondaCivic(); // still only 2 cars unset($myFriendCar); // one car left! printf("Number of compact cars: %d\n", CompactCar::getCount()); $myCar2 = clone $myCar; // now we have two cars again printf("Number of compact cars: %d\n", CompactCar::getCount()); CompactCar::$numCompactCars = 1000; // sorry, you can't do that! 
+3
source

It seems to me that you are trying to save data on an interface. This is not what interfaces can do. Interfaces are designed to describe what a class should look like from the outside, and not to actually implement functionality.

What you want is probably a regular class hierarchy, for example:

 class Car { public function doGeneralCarStuff() { //honk horn , blink blinkers, wipers on, yadda yadda } } class CompactCar extends Car { public static $numCompactCars = 0; public function __construct() { self::$numCompactCars++; } public function doCompactCarStuff() { //foo and bar and foobar } } class HondaCivic extends CompactCar { public function __construct() { parent::__construct(); // do Honda Civic stuff } } class ToyotaCorolla extends CompactCar { public function __construct() { parent::__construct(); // do Corolla stuff } } $myCar = new HondaCivic(); $myFriendCar = new ToyotaCorolla(); echo CompactCar::$numCompactCars; // -> 2 

The interface will be more suitable for describing a function that is not necessarily inherited, for example:

 interface HasSunroof { function openSunroof(); function closeSunroof(); } 

In some languages โ€‹โ€‹(Javascript, Ruby, etc.) HasSunroof can be โ€œmixinโ€ and have data and functionality associated with it, but in PHP (and Java, etc.) you have to put the functionality in a class that implements interface.

Interfaces (in my experience) are more often used in languages โ€‹โ€‹that check the type of compilation time, for example Java, than in "duck" languages โ€‹โ€‹like PHP.

+2
source

Source: https://habr.com/ru/post/1344228/


All Articles