天天看点

《Hack与HHVM权威指南》——1.5.2 覆盖方法的类型

在hack的代码之间,继承是更加复杂的相互关系中的一种。这复杂性主要来自于当继承关系被创建时,继承和被继承的代码之间的分离现象。举例来说,如果你有个类型标注为someclass的对象并可以调用这个对象的某个方法,那么你可以调用继承自someclass的任何类的某个方法。这个调用仍然需要是类型安全的,这就意味着覆盖其他方法的时候,方法的类型必须有一定的规则。

在一个覆盖方法中,参数类型必须和被覆盖的方法类型完全一致。这主要是因为继承自php的一个行为。在php中,任何覆盖自抽象方法或者接口中声明的覆盖方法,都必须精确地匹配被覆盖方法的参数类型。这在未来hack版本中的声明可能会有所改变,允许改变方法的参数类型将是更通常的做法。

换句话说,当进行方法覆盖时,覆盖方法的返回类型并不一定保持相同,相对于被覆盖的方法而言,覆盖方法可以有一个更加明确的返回类型。例如:

虽然改变了返回类型,这种多态的调用仍然是类型安全的。

function f(parentclass $obj) {

$number = $obj->generate();

// 即使$obj是个childclass实例,generate()方法自然会返回num类型

// 因为childclass::generate() 返回的是int类型,而所有int类型都属于num类型

用更通常的返回类型进行覆盖是非法的。例如,如果childclass的generate()方法被声明成返回类型为mixed的话,类型检查器将会报告错误。