【发布时间】:2010-12-07 16:13:42
【问题描述】:
我想知道是否允许在另一个类中创建一个类的实例。
或者,我是否必须在外部创建它,然后通过构造函数将其传入?但是我会在不知道是否需要它的情况下创建它。
示例(数据库类):
class some{
if(.....){
include SITE_ROOT . 'applicatie/' . 'db.class.php';
$db=new db
【问题讨论】:
我想知道是否允许在另一个类中创建一个类的实例。
或者,我是否必须在外部创建它,然后通过构造函数将其传入?但是我会在不知道是否需要它的情况下创建它。
示例(数据库类):
class some{
if(.....){
include SITE_ROOT . 'applicatie/' . 'db.class.php';
$db=new db
【问题讨论】:
我现在才看到这个,我想添加我的评论。它可能对任何人都有好处。有人听说过 php 特性吗?尽管traits不会导入另一个类,而只是将一个特征导入另一个类。因此,您可以拥有一个主类而不是尝试导入多个类,而子类将充当特征,使您可以在主/父类中使用它们
【讨论】:
abstract 类和父/子继承。在大多数情况下,特征在这里并不是一个好的解决方案
(编辑)好的,您尝试完成的问题和示例令人困惑。 从您的示例看来,您正试图在另一个类中定义一个类。
它的正确名称是 NESTED CLASS 并且在 PHP 中是不可能的。 因此,对于您的示例,答案是“否”。反正不在 PHP 中。其他语言将允许“嵌套类”。 Java 就是一个例子。
例如,这在 PHP 中不起作用
class outer_class{
class inner_class{
...
}
...
}
现在的问题是在另一个类中创建一个类的实例。
对此,答案是“是”,您可以在“类”中实例化一个“对象”。我们一直这样做。
class simple_class{
protected $instanceOfOtherClass;
public function instanciateObject_KeepingAReferenceToIt(){
// create an instance of OtherClass and associate it to $this->instanceOfOtherClass
$this->instanceOfOtherClass = new OtherClass();
}
public function instanciateObject_Without_KeepingAReferenceToIt(){
// create an instance of OtherClass and return it
return new OtherClass();
}
}
一个类甚至可以实例化自己。这就是著名的单身人士和许多其他Creational patterns 所做的事情。可悲的是,有些人认为知道dependency injection 意味着他们再也不会在方法中调用 NEW。错了。
【讨论】:
你不能在另一个类中定义一个类。您应该在类之外包含具有其他类的文件。在您的情况下,这将为您提供两个顶级课程db 和some。现在在some 的构造函数中,您可以决定创建db 的实例。例如:
include SITE_ROOT . 'applicatie/' . 'db.class.php';
class some {
public function __construct() {
if (...) {
$this->db = new db;
}
}
}
【讨论】:
require 而不是include。
require_once 更好:D
这在 PHP 7 中可以使用Anonymous classes。
参见the docs的示例:
class Outer
{
private $prop = 1;
protected $prop2 = 2;
protected function func1()
{
return 3;
}
public function func2()
{
return new class($this->prop) extends Outer {
private $prop3;
public function __construct($prop)
{
$this->prop3 = $prop;
}
public function func3()
{
return $this->prop2 + $this->prop3 + $this->func1();
}
};
}
}
echo (new Outer)->func2()->func3();
// Output: 6
这是一个简单的例子,展示了匿名类的用法,但不是来自一个类:
// Pre PHP 7 code
class Logger
{
public function log($msg)
{
echo $msg;
}
}
$util->setLogger(new Logger());
// PHP 7+ code
$util->setLogger(new class {
public function log($msg)
{
echo $msg;
}
});
【讨论】:
print_r(get_class_methods('Outer')); 打印 Array( [0] => func2 )
人们说可以“在一个类中创建一个类”似乎意味着可以在一个类中创建一个对象/实例。我没有在另一个类定义中看到实际类定义的示例,如下所示:
class myClass{
class myNestedClass{
}
}
/* THIS IS NOT ALLOWED AND SO IT WON'T WORK */
既然问题是'是否有可能创建一个类内部另一个类',我现在只能假设这是不可能的。
【讨论】:
不,这是不可能的。嵌套类和聚合对象是不同的机制。实际上,嵌套类意味着嵌套类名。嵌套在 B 类中的 A 类将被命名为“B\A”(?)。从 v5.3 开始,您可以在命名空间中嵌套类名(和其他一些名称)。
【讨论】:
我只是想指出,可以在另一个类定义中动态加载一个类定义。
Lukas 是对的,我们不能在另一个类中定义一个类,但是我们可以动态地 include() 或 require() 它们,因为包含文件中定义的每个函数和类都将具有全局范围。如果您需要动态加载类或函数,只需将文件包含在类的函数之一中即可。你可以这样做:
function some()
{
require('db.php');
$db = new Db();
...
}
【讨论】:
require_once 或include_once - 这样您将确保您没有多次包含/需要它:)
在 PHP 的另一个类中创建一个类是不可能的。 在另一个对象中创建一个对象(一个类的实例)是另一回事。
【讨论】: