Covariance and Contravariance in PHP

Covariance: In PHP, the return type of method which belongs to the child can be more specific compared to the return type of method of parent. This is done through covariance. For example, consider the parent class “Bank”, and “SB” and “BOI” to be its children.

filter_none

edit
close

play_arrow

link
brightness_4
code

<?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();
?>

chevron_right


Output:

Arshit has an SBI account
Simon has a BOI account

Contravariance: In PHP, the parameters of the method which belong to the child can be less specific compared to the parameters of the method of parent. This is done through contravariance.

filter_none

edit
close

play_arrow

link
brightness_4
code

<?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);
?>

chevron_right


Output:

Shreyank has account_no
Shrey has an SBI account_detail

Note: By excluding type limitings on parameters of the child method, partial contravariance was achieved in PHP version 7.2.0. and in PHP version 7.4.0, complete contravariance and covariance were achieved. All older versions before version 7.2.0 will show error.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.