【发布时间】:2013-11-29 04:40:27
【问题描述】:
第二次更新
我认为我一直在从错误的一面来解决这个问题。假设我应该将“First”作为一个抽象类并只是在以后找到一种引用“Second”和“Third”的方法,我是否正确?
更新
根据一些反馈,我添加了一些内容来尝试澄清我想做的事情。类似于这种效果的东西。
我只看下面的代码就知道,“如果”它确实有效,并且因为它没有,我知道我是从错误的角度解决问题。最终目标不是根据我使用的一些框架的猜测,所有这些都是不常见的。
我更想将这段特定的代码基于 CodeIgniter 方法,您可以在其中定义(如下)是 STR_CLASS_NAME 在配置文件中,然后在任何时候通过程序的操作,像我一样使用它口授。
STR_CLASS_NAME = 'Second';
class First {
protected $intTestOne = 100;
public function __construct() {
$strClassName = STR_CLASS_NAME;
return new $strClassName();
}
public function TestOne() {
echo $this->intTestOne;
}
protected function TestThreePart() {
return '*Drum ';
}
}
class Second extends First{
/* Override value to know it's working */
protected $intTestOne = 200;
/* Overriding construct to avoid infinite loop */
public function __construct() {}
public function TestTwo() {
echo 'Using method from extended class';
}
public function TestThree() {
echo $this->TestThreePart().'roll*';
}
}
$Test = new First();
$Test->TestOne(); <-- Should echo 200.
$Test->TestTwo(); <-- Should echo 'Using method from extended class'
$Test->TestThree(); <-- Should echo '*Drum roll*'
你可能会问,为什么要这样做而不是仅仅实例化 Second,嗯,有些情况会略有不同:
STR_CLASS_NAME = 'Third';
class Third extends First{
/* Override value to know it's working */
protected $intTestOne = 300;
/* Overriding construct to avoid infinite loop */
public function __construct() {}
public function TestTwo() {
echo 'Using method from extended class';
}
public function TestThree() {
echo $this->TestThreePart().'snare*';
}
}
$Test = new First();
$Test->TestOne(); <-- Should echo 300.
$Test->TestTwo(); <-- Should echo 'Using method from extended class'
$Test->TestThree(); <-- Should echo '*Drum snare*'
情况
我有一个抽象类,它用实际实现扩展了一个基类;在本例中是一个基本的 DB 包装器。
class DBConnector ()
class DBConnectorMySQLi extends DBConnector()
如您所见,MySQLi 是实现。现在,根据配置过程中的值,一个常量成为我希望使用的类名,在这种情况下(如下所示构建 DBConnectorMySQLi。
define('STR_DB_INTERFACE', 'MySQLi');
define('DB_CLASS', 'DBConnector'.STR_DB_INTERFACE);
目标
- 拥有一个可以扩展以包含实现的基类
- 对于代码本身不需要知道实现的名称实际上是什么
- (在这种情况下)能够键入或使用项目接受的公共变量来创建 DBConnectorMySQLi。 IE。 $db 或类似的东西。 W
问题
在实际调用这个类时,我希望代码如下所示。我想知道这是否完全可能不需要添加任何额外的语法。附带说明一下,这个常数是 100% 保证被定义的。
$DBI = new DB_CLASS();
解决方案 1
我知道可以使用反射类(如 THIS QUESTION 中所讨论的那样),它通过以下方式工作:
$DBI = new ReflectionClass(DB_CLASS);
但是,这会创建比预期“更脏”的代码
解决方案 2
在DBConnector的构造函数中启动DBConnectorMySQLi的具体实现。
define('STR_DB_INTERFACE', 'MySQLi');
define('DB_CLASS', 'DBConnector'.STR_DB_INTERFACE);
class DBConnector() { public function __construct() { $this->objInterface = new DBConnectorMySQLi(); }
class DBConnectorMySQLi()
然而,这将导致需要继续将变量从一个“推”到另一个
任何建议都非常感谢
【问题讨论】:
-
我最终要做的(而不是试图扭曲不想被扭曲的东西)是(根据给出的示例)“首先”一个抽象类,并且只有其他人扩展它。现在,这个练习的重点是,当涉及到操作时,可以很容易地为不同的接口编写一次代码,所以有一个基本的服务控制器 E.G.针对多个数据库或为不同的传输方法呈现内容,所有这些都使用相同的“内容库”。 DRY 原则和依赖注入仍然盛行。
标签: php class inheritance