PHP中多重继承的解决方法?
在我的很多 PHP 类中,我都有这样的代码:
private $strError = "";
private $intErrorCode = NULL;
private $blnError = FALSE;
public function isError() {
return $this->blnError;
}
public function getErrorCode() {
return $this->intErrorCode;
}
private function setError( $strError, $intErrorCode = NULL ) {
$this->blnError = TRUE;
$this->intErrorCode = $intErrorCode;
$this->strError = $strError;
}
重点是让外部代码可以知道对象是否有错误状态、错误的字符串是什么等。但是要将这些确切的代码放在一堆中不同的班级是重复的!
我希望有一个双重扩展,我可以这样做,
class childClass extends parentClass, error {
...
}
并且拥有这些天生的属性和方法,但是 PHP 不支持多重继承。我正在考虑做的是创建一个存在于每个类中的错误类。如果我将其公开,我可以直接通过对象调用它,
if ( $myObject->error->isError() ) {...}
但这是否也会使其错误状态可以从包含类的外部设置,
$myObject->error->setError("I shouldn't be doing this here");
这是我宁愿避免的?
或者我可以在包含的类中编写“网关”函数,这些函数对错误对象进行适当的调用,并防止从外部设置错误状态,
class childClass extends parentClass {
private $error;
public function __construct(...) {
...
$error = & new error();
...
}
public function isError() {...}
public function getError() {...}
public function getErrorCode() {...}
private function setError() {...}
...
}
但这会导致(某些)代码重复,这是我试图避免的。
这里的最佳解决方案是什么?我正在尝试为许多对象提供错误状态功能,以便外界可以以最少的重复次数看到它们的错误状态。
In a lot of my PHP classes, I have this code:
private $strError = "";
private $intErrorCode = NULL;
private $blnError = FALSE;
public function isError() {
return $this->blnError;
}
public function getErrorCode() {
return $this->intErrorCode;
}
private function setError( $strError, $intErrorCode = NULL ) {
$this->blnError = TRUE;
$this->intErrorCode = $intErrorCode;
$this->strError = $strError;
}
The point is so that outside code can know if an object has an error state, what the string of the error is, etc. But to have this exact code in a bunch of different classes is repetitious!
I'd love to have a dual-extension where I could do
class childClass extends parentClass, error {
...
}
And have those properties and methods inborn, But PHP doesn't support multiple inheritances. What I'm thinking about doing is creating an error class that exists inside each class. If I make it public, I can call it directly through the object
if ( $myObject->error->isError() ) {...}
but wouldn't that also make its error status settable from outside the containing class,
$myObject->error->setError("I shouldn't be doing this here");
which I would rather avoid?
Or I could write 'gateway' functions in the containing class, which do the appropriate calls on the error object, and prevent setting the error status from outside,
class childClass extends parentClass {
private $error;
public function __construct(...) {
...
$error = & new error();
...
}
public function isError() {...}
public function getError() {...}
public function getErrorCode() {...}
private function setError() {...}
...
}
but that leads to (some of) the code duplication that I'm trying to avoid.
What's the optimal solution here? I'm trying to have functionality for error statuses for a number of objects, so that the outside world can see their error state, with minimal repetition.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用组合而不是继承。
现在使用私有实例变量来引用它:
private
可见性可防止您在类外部引用$errors
。也无需在
childClass
内创建isError()
、getError()
等(因此无需担心代码重复) 。只需调用$this->errors->isError()
、$this->errors->getError()
等。如果您仍想要求不过,正如下面所建议的,您可以指定一个接口来实现这些方法。Use composition instead of inheritance.
And now use a private instance variable to refer to it:
The
private
visibility prevents you from referencing$errors
outside of the class.There's also no need to create
isError()
,getError()
, etc. insidechildClass
(and therefore no need to worry about code duplication). Simply call$this->errors->isError()
,$this->errors->getError()
, etc. If you still wanted to require those methods to be implemented though, as suggested below, you could specify an interface.您还可以滥用 __call 魔术方法来完成同样的事情:
请注意,我说的是滥用...理想情况下,我会考虑一种不同的架构,而不是到处都有这些“通用方法”。为什么不使用异常而不是检查
$foo->isError
?如果这不合适,为什么不装饰一个类呢?然后只需将现有对象“包装”在该类中即可:
You could also abuse the
__call
magic method to do the same thing:Note that I said abuse... Ideally, I'd think of a different architecture rather than having all these "common methods" everywhere. Why not use an exception instead of checking
$foo->isError
? If that's not appropriate, why not decorate a class?Then just "wrap" your existing object in that class:
从 PHP 5.4 开始,您可以使用 Traits。
例如,您可以将 Trait 称为 ErrorTrait,如下所示:
然后您可以像这样定义您的子类:
Trait 的工作方式基本上类似于复制/粘贴,因此 Trait 中的所有代码都可以在该类中使用(没有代码重复)。
As of PHP 5.4, you can use Traits.
For example you could make Trait called ErrorTrait like this:
Then you would define your child class like this:
Traits work basically like copy/paste so all of the code in the trait would be available within the class (without the code duplication).