As far as I know,
when a class extending another class, It’s should override all abstract methods of parent class and It can also override non-abstract methods
And also when a class implementing an interface, It’s should override all of the parent interface methods
but I’ve seen a Laravel project that didn’t do this
This is the parent interface:
<?php
interface MustVerifyEmail
{
/**
* Determine if the user has verified their email address.
*
* @return bool
*/
public function hasVerifiedEmail();
/**
* Mark the given user's email as verified.
*
* @return bool
*/
public function markEmailAsVerified();
/**
* Send the email verification notification.
*
* @return void
*/
public function sendEmailVerificationNotification();
/**
* Get the email address that should be used for verification.
*
* @return string
*/
public function getEmailForVerification();
}
this is the parent class:
<?php
class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}
and this is the child class:
<?php
use IlluminateContractsAuthMustVerifyEmail;
use IlluminateFoundationAuthUser as Authenticatable;
class User extends Authenticatable implements MustVerifyEmail
{
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
public function activeCode()
{
return //...
}
public function hasTwoFactor($key)
{
return //...
}
public function isTwoFactorAuthEnabled()
{
return //...
}
}
How did this happen?
2
Answers
In Laravel, you can implement interfaces without explicitly declaring all the methods of the interface in your class. Instead, Laravel uses "implicit implementation," where the framework dynamically resolves the implementation based on naming conventions and method signatures.
TLDR: User model inherits the implementation from its parent model, while the later delegated the implementation to
trait MustVerifyEmail
.Hello mahdi_sheykh. These methods were actually explicitly implemented, just not on the class itself but on its
traits
.In this particular case you might be confused by two homonym oop structures:
interface MustVerifyEmail
vstrait MustVerifyEmail
. Your User model states that the interface will be implemented by it, which is true but not strictly because the one actually implementing it is the parent classAuthenticatable
. But when did it implement it? That is where theuse
keyword gets into action:While
implements
is for Interfaces, theuse
is for Traits. Parent User class is "using" thetrait MustVerifyEmail
, in other words, it is attaching the trait to itself, thus "inheriting" all of its methods.