Covarianza: en PHP, el tipo de retorno del método que pertenece al hijo puede ser más específico en comparación con el tipo de retorno del método del padre. Esto se hace a través de la covarianza. Por ejemplo, considere la clase padre «Banco», y «SB» y «BOI» como sus hijos.
<?php // Parent class declared abstract class bank { protected $name; public function __construct( $name) { $this->name = $name; } abstract public function account(); } // Child 1 class SBI extends bank { public function account() { echo $this->name . " has an SBI account"; } } // Chil2 class BOI extends bank { public function account() { echo $this->name . " has a BOI account"; } } interface acc_open { public function open($name): bank; } class SBI_acc_open implements acc_open { // Not returning the parent class // type but the child's return // type instead public function open($name): SBI { return new SBI($name); } } class BOI_acc_open implements acc_open { // Not returning the parent class // type but the child's return // type instead public function open( $name) : BOI { return new BOI($name); } } $a = (new SBI_acc_open)->open("Arshit"); $a->account(); echo "\n"; $b = (new BOI_acc_open)->open("Simon"); $b->account(); ?>
Producción:
Arshit has an SBI account Simon has a BOI account
Contravarianza: en PHP, los parámetros del método que pertenecen al hijo pueden ser menos específicos en comparación con los parámetros del método del padre. Esto se hace a través de la contravarianza.
<?php // Parent class declared abstract class bank { protected $name; public function __construct( $name) { $this->name = $name; } public function acc_no(account_no $n) { echo $this->name . " has " . get_class($n); } } // Child 1 class SBI extends bank { public function account() { echo $this->name . " has an SBI account "; } // The function acc_no is overridden in // the class SBI that allows any // account_detail type object, it will // show contravariance behavior public function acc_no(account_detail $n) { echo $this->name . " has an SBI " . get_class($n); } } // Child2 class BOI extends bank { public function account() { echo $this->name . " has a BOI account"; } } interface acc_open { public function open($name): bank; } class SBI_acc_open implements acc_open { // Not returning the parent class type // but the child's return type instead public function open($name): SBI { return new SBI($name); } } class BOI_acc_open implements acc_open { // Not returning the parent class type // but the child's return type instead public function open( $name) : BOI { return new BOI($name); } } class account_detail{} class account_no extends account_detail{} $k = (new BOI_acc_open)->open("Shreyank"); $c = new account_no(); $k->acc_no($c); echo("\n"); $y = (new SBI_acc_open)->open("Shrey"); $d = new account_detail(); $y->acc_no($d); ?>
Producción:
Shreyank has account_no Shrey has an SBI account_detail
Nota: al excluir las limitaciones de tipo en los parámetros del método secundario, se logró una contravarianza parcial en la versión 7.2.0 de PHP. y en PHP versión 7.4.0, se lograron contravarianza y covarianza completas. Todas las versiones anteriores a la versión 7.2.0 mostrarán un error.