我正在研究语言约束对帐系统的下一个版本。我从这开始(abstract
函数声明似乎是问题):
namespace AAABIT;
abstract class LangPrefSet{
private $LangPrefs;
public function __construct(){$this->LangPrefs=array();}
public function add(LangPref $langpref){$this->LangPrefs[]=$langpref;}
public function langPrefs(){return $this->LangPrefs;}
abstract public function reconcile(LangPrefSet $other);//←Seems to be throwing an error… We don't strictly need this line, but this is a little concerning…
protected static function reconcile_LangPrefSets(LangPrefSet_ForUser $UserLangPrefSet,LangPrefSet_Resource $RsrcLangPrefSet,$maxOptions){//…
}
}
//Following classes are necessary because language similarity is a one-way mapping. Just because resources in Lang A (e.g. Russian) are likely to be readily understandable for speakers/readers of Lang B (e.g. Ukrainian), does not mean that the resources in Lang B (e.g. Ukrainian) are equally intelligible for speakers/readers of Lang A (e.g. Russian)!
class LangPrefSet_For_User extends LangPrefSet{public function reconcile(LangPrefSet_Resource $RsrcLangPrefSet){return self::reconcile_LangPrefSets(self,$RsrcLangPrefSet);}}
class LangPrefSet_Resource extends LangPrefSet{public function reconcile(LangPrefSet_For_User $UserLangPrefSet){return self::reconcile_LangPrefSets($UserLangPrefSet,self);}}
我认为这会有效,因为LangPrefSet_Resource符合LangPrefSet;但PHP发现这令人反感,抛出了上述错误。我以为我可能会更好地使用界面...所以我这样做了:
interface LangPrefSet_Reconcilable{
public function reconcile(LangPrefSet_Reconcilable $other);
}
然后我使两个类扩展了LangPrefSet,implements LangPrefSet_Reconcilable
,并注释掉了抽象函数声明(在第一次尝试制作之后需要一个LangPrefSet_Reconcilable
接口类型的参数,也没有这个参数。工作) - 结果是:
Fatal error: Declaration of AAABIT\LangPrefSet_For_User::reconcile() must be compatible with AAABIT\LangPrefSet_Reconcilable::reconcile(AAABIT\LangPrefSet_Reconcilable $other)
- 这对我来说不是一个阻碍问题,因为我可以删除abstract function
和interface
,系统会正常工作。但是,我担心我可能没有正确理解接口/抽象类!
指定覆盖abstract function a(ObjB $b)
或类似接口规范的类方法作为参数ObjC $c
,ObjC扩展ObjB有什么问题?
答案 0 :(得分:0)
您的参数类型在接口(或抽象类)中必须相同,并且您要实现相同的参数类型。现在界面是LangPrefSet_Reconcilable
并且实施说LangPrefSet_Resource
和LangPrefSet_For_User
。
您可以使用下面的第二个界面,也可以使用同一个类。
interface LangPrefSetReconcilableDataInteface {
...
}
interface LangPrefSet_Reconcilable{
public function reconcile(LangPrefSetReconcilableDataInteface $other);
}
class LangPrefSet_Resource implements LangPrefSetReconcilableDataInteface {
...
}
class LangPrefSet_For_User implements LangPrefSetReconcilableDataInteface {
...
}
class LangPrefSet_For_User extends LangPrefSet
{
public function reconcile(LangPrefSetReconcilableDataInteface $RsrcLangPrefSet)
{
return self::reconcile_LangPrefSets(self,$RsrcLangPrefSet);
}
}
class LangPrefSet_Resource extends LangPrefSet
{
public function reconcile(LangPrefSetReconcilableDataInteface $UserLangPrefSet)
{
return self::reconcile_LangPrefSets($UserLangPrefSet,self);
}
}
答案 1 :(得分:0)
问题可能是在抽象类声明中,我指定任何 LangPrefSet
必须是reconcile()
对象方法可接受的:
abstract public function reconcile(LangPrefSet $other);
- 在实际的方法声明中,我在一个案例中指定仅一个LangPrefSet_Resource
是可以接受的,而在另一个案例中,仅 LangPrefSet_For_User
是可以接受的。
因此,对象方法声明与抽象方法声明不兼容。似乎这些接口/抽象方法声明技术的正确应用不是为了扩展实现接口的类中允许的参数类型约束的范围,因为我们可以简单地通过声明输入限制来实现这一点,因为它们应该适用于那些具体课程/方法;但是,接口/抽象方法声明旨在扩大可能实际传递给指定这些抽象参数类型的方法的参数范围。