我们可以在php中的另一个类中创建一个类的对象吗?我在php中创建了一个小应用程序,现在我试图以类方法对象的方式转换整个代码。我现在很困惑。< / p>
答案 0 :(得分:17)
你可以这样做,但是否应该取决于两个班级的生命周期及其相互关系。基本上,您可以选择Composition和Aggregation。
当创建的对象的生命周期等于或小于将使用它的对象时,使用Composition,例如
class A
{
private $belongsToAOnly;
public function __construct()
{
$this->belongsToAOnly = new IBelongToA;
}
}
在这种情况下,A
“拥有”IBelongToA
。当A
被销毁时,IBelongToA
也会被销毁。它不能独立存在,可能只是A
的实现细节。它可以是ValueObject,例如Money
或其他一些数据类型。
来自Craig Larman的“应用UML和模式”:
复合材料负责创建和删除它的部分 - 通过自己创建/删除部分,或通过与其他对象协作。与此约束相关的是,如果复合材料被销毁,则必须销毁其零件,或将其附加到另一个复合材料“
当创建的对象的生命周期更长时,您使用聚合:
class A
{
private $dbAdapter;
public function __construct(DbAdapter $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
}
}
与Composition不同,这里没有所有权的含义。 A
使用DbAdapter
,但A
被销毁时DBAdapter
仍然存在。这是一种“使用”关系,而不是“拥有”关系。
可以在Creator Pattern in GRASP中找到一个很好的启发式方法来确定对象何时可以在运行时创建另一个对象,该{... 3}表示对象可能会创建其他对象
- B的实例包含或复合聚合A
的实例- A
的B记录实例的实例- B的实例密切使用A
的实例- B的实例具有A实例的初始化信息,并在创建时传递。
或者,您可以在需要创建某些实例并聚合工厂实例时创建工厂,这样可以为您提供更清晰的separation of collaborators and creators。
在对象中创建对象所产生的问题是它们很难测试。当您进行单元测试时,通常不希望重新创建和引导整个系统环境,而是专注于单独测试该特定类。为此,您将该类的依赖项换成Mock Objects。使用Composition时,不能这样做。
因此,根据类的协作者所做的事情,您可能希望决定始终使用聚合,因为这样您就可以一直有效地执行Dependency Injection,这将允许您交换类的协作者很容易,例如用Mocks替换它们。
答案 1 :(得分:6)
是的,你可以,但这增加了代码耦合并使测试更加困难 我建议在类之外创建它并将其作为参数传递(它称为依赖注入)。
class Foo
{
}
class Bar
{
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
}
$foo = new Foo();
$bar = new Bar($foo);
答案 2 :(得分:4)
是的,你可以做到。
这是一个例子..
a.php
<?php
class a{
public function function_1(){
echo "b";
}
}
?>
b.php
<?php
include_once ("a.php");
class b{
public function function_b(){
$a = new a;
$a->function_1();
}
}
$b= new b;
$b->function_b();
?>
答案 3 :(得分:3)
是的,您可以从另一个类中创建特定类的对象。
class SomeClass{
}
class SomeOtherClass {
function hello(){
$o = new SomeClass;
}
}
答案 4 :(得分:2)
是的,你也可以在一个类中定义一个函数。你可以在php的课堂上做所有事情,请把你的代码发布到困惑的地方。
实施例: 类中的对象。
class Foo
{
public $bar; // another object!
public __construct()
{
$this->bar = new Bar();
}
}
(全局)类中的函数
<?php
class Foo
{
public function __construct()
{
function __construct()
{
echo "Yes, I'm a global function!";
}
}
}
new Foo();
__construct();
?>