📜  PHP的协方差和逆变

📅  最后修改于: 2022-05-13 02:24:08.718000             🧑  作者: Mango

PHP的协方差和逆变

协方差:在PHP,与父方法的返回类型相比,属于子的方法的返回类型可以更具体。这是通过协方差完成的。例如,将父类“Bank”、“SB”和“BOI”视为其子类。

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

输出:

Arshit has an SBI account
Simon has a BOI account

逆变:在PHP,与父方法的参数相比,属于子方法的参数可以不那么具体。这是通过逆变完成的。

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

输出:

Shreyank has account_no
Shrey has an SBI account_detail

注意:通过排除子方法参数的类型限制, PHP 7.2.0 版实现了部分逆变。而在PHP 7.4.0 版本中,实现了完全的逆变和协变。 7.2.0 之前的所有旧版本都会显示错误。