Php 当父构造函数是公共的时,如何使子构造函数成为私有的?
为什么不可能在子类中隐藏构造函数 我得到以下例外情况: 致命错误:必须具有对CIS\Logger\WPLogger::\uu构造()的访问级别 在中公开(如Katzgrau\KLogger\Logger类) /builds/r2o/website/wp content/mu plugins/toolsets/lib/cis logger/src/wpgger.php 在线12 超类代码(来自外部库): WPLogger.php的代码(子类):Php 当父构造函数是公共的时,如何使子构造函数成为私有的?,php,class,oop,inheritance,constructor,Php,Class,Oop,Inheritance,Constructor,为什么不可能在子类中隐藏构造函数 我得到以下例外情况: 致命错误:必须具有对CIS\Logger\WPLogger::\uu构造()的访问级别 在中公开(如Katzgrau\KLogger\Logger类) /builds/r2o/website/wp content/mu plugins/toolsets/lib/cis logger/src/wpgger.php 在线12 超类代码(来自外部库): WPLogger.php的代码(子类): 我不想用new实例化这个特殊的子类。出于某些原因,我
我不想用
new
实例化这个特殊的子类。出于某些原因,我希望使用getInstance()
静态创建它。如何实现这一点?实际上没有任何方法可以强制子类接受比您要覆盖的父函数更低级别的函数
这里您可能需要的是一个包装器类,它模拟父类,但不扩展它
class Singleton {
/** @var \Katzgrau\KLogger\Logger */
protected $logger;
/** @var Singleton */
protected $instance;
private function __construct($someargs) {
$this->logger = new \Katzgrau\KLogger\Logger($someargs);
}
public static function getInstance($someargs) {
if($this->instance instanceof Singleton) return $this->instance;
$this->instance = new self($someargs);
return $this->instance;
}
/** Magic method to pass along calls to the other class */
function __call($method, $args) {
call_user_func_array(array($this->logger, $method), $args);
}
}
不能使子类方法(在本例中是构造函数,但应用相同的原则)比父类更严格。因为将使用该类型的客户机代码期望具有与超级类相同的契约/接口。否则,不能透明地用类的实例替换超类的实例,反之亦然 但是,您的超类依赖于
AbstractLogger
,它从Psr\Log\LoggerInterface
实现。因为我确信每个人都遵循依赖倒置原则,所以您应该能够说,wpgogger
直接从LoggerInterface
实现是很好的。因此:
use Psr\Log\LoggerInterface;
final class WPLogger implements LoggerInterface
{
private $wrapperLogger;
private function __construct() {}
public static function getInstance(string $logFileRelative = self::DEFAULT_LOG_NAME, string $logLevelThreshold = LogLevel::DEBUG, array $options = array()) {
// @TODO, implement here your singleton if you want
$self = new self();
$self->wrapperLogger = new \Katzgrau\KLogger\Logger(...);
return $self;
}
// implement the rest of the interface, delegating to wrapperLogger
}
您可以使用继承来扩展方法的可见性。下面的例子是正确的
class A
{
private function __construct()
{}
}
class B extends A
{
public function __construct()
{}
}
但您无法限制方法在子类中的可见性。下面的例子是不正确的
class A
{
public function __construct()
{}
}
class B extends A
{
private function __construct()
{}
}
在您的例子中,您试图隐藏构造函数,因为您希望生成单例。单身在很多情况下都是不好的习惯。你应该使用
对象生成的其他模式:
例如,您可以通过对静态工厂的简单修改来归档必要的结果:
class LoggerFactory
{
private static $instance = null;
public static function build()
{
if (is_null(static::$instance)) {
static::$instance = // making of the logger
}
return static:$instance;
}
}
超类是否实现了接口?否:
扩展了AbstractLogger
,但没有接口。每个答案都提供了一个很好的解决方法。对于我的案例,我认为你的工厂是最好的主意。一个很好的解决方案,带有接口,仅对于我当前的案例,我决定使用工厂模式解决它。对于我当前的案例,也是一个好主意,我决定继续使用建议的工厂解决方案。
class A
{
public function __construct()
{}
}
class B extends A
{
private function __construct()
{}
}
class LoggerFactory
{
private static $instance = null;
public static function build()
{
if (is_null(static::$instance)) {
static::$instance = // making of the logger
}
return static:$instance;
}
}