📜 ⬆️ ⬇️

Getting ready for a PHP interview: Everything you wanted to know about interfaces, signature compatibility and were not afraid to learn

image Interfaces, having first appeared in PHP 5, have long taken a firm place in the object-oriented (or are they still more correct than the “class-oriented”?) Part of the language.

It would seem - what could be simpler interface? " As if a class, but not a class, it is impossible to create an instance, rather a contract for future classes, contains the headers of public methods " - isn’t it, with such words you most often answer an interview on the duty question of what an interface is ?

However, not everything is as simple as it might seem to a novice PHP programmer. The usual analogies do not work, the language guide misleads you, unexpected “pitfalls” are hidden in the code ...
')
Three previous parts:


What can the interface contain?


It is obvious that public methods, and without implementation: immediately after the header (signature) of the method should be terminated with a semicolon:

interface SomeInterface { public function foo(); public static function bar(Baz $baz); } 

A little less obvious (although described in the manual) is the fact that the interface can contain constants (of course, only public!):

 interface SomeInterface { public const STATUSES = [ 'OK' => 0, 'ERROR' => 1, ]; } if (SomeInterface::STATUSES['OK'] === $status) { // ... } 

Why are constants in interfaces not widely used in industrial code, although they are sometimes used? The reason is that they cannot be redefined in the inheritance interface or in the class that implements this interface. Interface constants are the most constant constants in the world :)

What can't the interface contain?


More can not. In addition to the headings of public methods and public constants.

You can not include in the interface:


In fact, in fact, he and the interface!

Method Signature Compatibility


For further study of the interfaces, you and I need to learn about the most important concept, which is undeservedly overlooked in the PHP manual: the concept of "signature compatibility".

A signature is a description of a function (method), including:


Examples:

 function (); public function foo($arg = null); protected function sum(int $x, int $y, ...$args): int; 

Suppose we have two functions, A and B.
The signature of function B is considered compatible with A (the order is important, the relation is asymmetrical!) In the strict sense if:

They completely coincide.


The trivial case, there is nothing to comment on.

B adds default arguments to A


A:

 function foo($x); 

Compatible B:

 function foo($x, $y = null); function foo($x, ...$args); 

B narrows the range of A values


A:

 function foo(int $x); 

Compatible B:

 //  A    ,  B        function foo(int $x): int; 

Now that we have introduced these three simple definition compatibility rules, it will be much easier to understand the further subtleties associated with interfaces.

Interface Inheritance


Interfaces can be inherited from each other:

 interface First { public const PI = 3.14159; public function foo(int $x); } interface Second extends First { public const E = 2.71828; public function bar(string $s); } assert(3.14159 === First::PI); assert(true === method_exists(First::class, 'foo')); assert(3.14159 === Second::PI); assert(2.71828 === Second::E); assert(true === method_exists(Second::class, 'foo')); assert(true === method_exists(Second::class, 'bar')); 

The inheritor interface inherits from the ancestor interface all the methods and constants defined in the ancestor.

In the heir interface, you can override the method from the parent interface. But only under the condition that either its signature coincides exactly with the signature of the parent, or is compatible (see the previous section):

 interface First { public function foo(int $x); } interface Second extends First { //  ,   public function foo(int $x); //  ,   Declaration must be compatible public function foo(int $x, int $y); //  ,        -      public function foo(int $x, int $y = 0); //   ,    "..."   public function foo(int $x, ...$args); //     public function foo(int $x, ...$args): int; } 

Does PHP have multiple inheritance?


If you are asked such a question, feel free to answer: "yes . " The interface can be inherited from several other interfaces.

Now you have seen everything:

 interface First { public function foo(int $x); } interface Second { public function bar(string $s); } interface Third extends First, Second { public function baz(array $a); } assert(true === method_exists(Third::class, 'foo')); assert(true === method_exists(Third::class, 'bar')); assert(true === method_exists(Third::class, 'baz')); 

The rules for resolving conflicts of method signatures with multiple inheritance are exactly the same as we have already seen above:

- either the signatures match completely
- either the signature of the method of the interface mentioned first in the list of ancestors must be compatible with the signature of the second ancestor (yes, the order of mention matters, but this is a very rare case, just never take it into account)

Interface implementation subtleties


Actually, after all that you have already seen, it is no longer subtleties, but so, small nuances.

Firstly, class inheritance from an interface is called implementation. The point is that you do not just inherit methods and constants, but must implement those methods that are specified by signatures, fill them with code:

 interface IntSumInterface { public function sum(int $x, int $y): int; } interface IntMultInterface { public function mult(int $x, int $y): int; } class Math implements IntSumInterface, IntMultInterface { public function sum(int $x, int $y): int { return $x + $y; } public function mult(int $x, int $y): int { return $x * $y; } } 

An important aspect that distinguishes the implementation of an interface from inheritance from another class is the ability to implement several interfaces in one class at once.

What if the same method (with the same name) is implemented in different interfaces that the class implements? See above - as well as when inheriting interfaces from each other, the principle of signature compatibility must be observed.

And yes. Do not believe the manual, which proclaims:
The signatures of the methods in the class that implements the interface must exactly match the signatures used in the interface, otherwise a fatal error will be caused.

It should be noted that the same method signatures as it is defined in the interface. Fatal error.

Everything is wrong, the same compatibility rule works:

 interface SomeInterface { public function sum(int $x, int $y); } class SomeClass implements SomeInterface { public function sum(int $x, int $y): int  public function sum(int $x, int $y, int $z = 0): int   public function sum(int $x, int $y, ...$args): int { //   } } 

Is the interface a class? Pro et contra


Actually, no. An interface is an interface; it differs from a class even if it is impossible to create an “interface instance”.

And actually, yes, they have a lot in common in PHP:

  1. Interfaces, like classes, can be in namespaces.
  2. Interfaces, like classes, can be loaded via the autoload mechanism. The autoload function will be passed in the full name of the interface (with the namespace).
  3. Each interface has a predefined constant ThisInterface :: class containing its full name.
  4. The interface, as well as the class, can participate on the right in the instanceof operator
  5. An interface, like a class, can be specified as a type in type hinting (specifying the type of the argument or the return value of the function)

What to read on the night before a responsible interview?


Of course, the manual for the language:


But it is much better to read heavy technical texts not in the last night, but in advance.

A systematic approach to self-education in programming is very important. And, in my opinion, not bad at the beginning of the way to IT help to structure self-learning webinars and short-term courses. That is why I recommend (and advertise a little modestly) even experienced developers to attend one-time webinars and refresher courses - the result with the right combination of courses and self-preparation is always there!

Successes on interview and in work!

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


All Articles