它对于以下测试用例似乎很有效(尽管它确实发出了严格警告):
class PassMeIn{}class PassMeInSubClass extends PassMeIn{}class ClassProcessor{ public function processClass (PassMeIn $class) { var_dump (get_class ($class)); }}class ClassProcessorSubClass extends ClassProcessor { public function processClass (PassMeInSubClass $class) { parent::processClass ($class); }}$a = new PassMeIn;$b = new PassMeInSubClass;$c = new ClassProcessor;$d = new ClassProcessorSubClass;$c -> processClass ($a);$c -> processClass ($b);$d -> processClass ($b);如果严格警告不是您真正想要的,则可以这样解决。
class ClassProcessor{ public function processClass (PassMeIn $class) { var_dump (get_class ($class)); }}class ClassProcessorSubClass extends ClassProcessor { public function processClass (PassMeIn $class) { if ($class instanceof PassMeInSubClass) { parent::processClass ($class); } else { throw new InvalidArgumentException; } }}$a = new PassMeIn;$b = new PassMeInSubClass;$c = new ClassProcessor;$d = new ClassProcessorSubClass;$c -> processClass ($a);$c -> processClass ($b);$d -> processClass ($b);$d -> processClass ($a);不过,您应该记住一件事,这绝对不是OOP方面的最佳实践。如果超类可以接受特定类的对象作为方法参数,则其所有子类也应也可以接受该类的对象。防止子类处理超类可以接受的类意味着您不能使用子类代替超类,并且要100%确信它在所有情况下都可以使用。相关实践称为Liskov替代原理,它指出,除其他外,方法参数的类型只能在子类中变弱,而返回值的类型只能变强(输入只能变得更通用,输出可以仅获得更具体的信息)。
这是一个非常令人沮丧的问题,我本人已经多次尝试反对它,因此,如果在特定情况下忽略它是最好的选择,那么我建议您忽略它。但是请不要养成它的习惯,否则您的代码将开始开发各种微妙的相互依赖关系,这将是调试的噩梦(单元测试无法捕获它们,因为各个单元的行为均符合预期,这是它们之间的相互作用问题所在)。如果您确实忽略了它,那么请注释该代码以使其他人知道它,这是一个有意的设计选择。



