PHP中的嵌套或内部类

我正在为新网站构建 ,但是这次我在考虑构建它有点不同…

, 甚至

(可能还有其他编程语言)都允许在主类内部使用嵌套/内部类,这使我们可以使代码更加面向对象和组织化。

PHP中,我想这样做:

<?php

public class User {

public $userid;

public $username;

private $password;

public class UserProfile {

// some code here

}

private class UserHistory {

// some code here

}

}

?>

这在PHP中可行吗?我该如何实现?


如果不可能,将来的PHP版本是否会支持嵌套类?

回答:

回答:

嵌套类与其他类的关系与外部类略有不同。以Java为例:

非静态嵌套类可以访问封闭类的其他成员,即使它们被声明为私有的也是如此。同样,非静态嵌套类要求实例化父类的实例。

OuterClass outerObj = new OuterClass(arguments);

outerObj.InnerClass innerObj = outerObj.new InnerClass(arguments);

使用它们有几个令人信服的原因:

  • 这是一种对仅在一个地方使用的类进行逻辑分组的方法。

如果一个类仅对其他一个类有用,那么将其关联并嵌入该类并将两者保持在一起是合乎逻辑的。

  • 它增加了封装。

考虑两个顶级类A和B,其中B需要访问A的成员,否则将其声明为私有。通过将类B隐藏在类A中,可以将A的成员声明为私有,而B可以访问它们。另外,B本身可以对外界隐藏。

  • 嵌套类可以导致更具可读性和可维护性的代码。

嵌套类通常与其父类相关,并一起形成一个“包”

回答:

如果没有嵌套类,则在PHP中可以具有 类似的 行为。

如果您要实现的只是结构/组织,如Package.OuterClass.InnerClass,则PHP名称空间可能就足够了。您甚至可以在同一文件中声明多个名称空间(尽管由于标准的自动加载功能,可能不建议这样做)。

namespace;

class OuterClass {}

namespace OuterClass;

class InnerClass {}

如果您希望模拟其他特征,例如成员可见性,则需要花费更多的精力。

回答:

namespace {

class Package {

/* protect constructor so that objects can't be instantiated from outside

* Since all classes inherit from Package class, they can instantiate eachother

* simulating protected InnerClasses

*/

protected function __construct() {}

/* This magic method is called everytime an inaccessible method is called

* (either by visibility contrains or it doesn't exist)

* Here we are simulating shared protected methods across "package" classes

* This method is inherited by all child classes of Package

*/

public function __call($method, $args) {

//class name

$class = get_class($this);

/* we check if a method exists, if not we throw an exception

* similar to the default error

*/

if (method_exists($this, $method)) {

/* The method exists so now we want to know if the

* caller is a child of our Package class. If not we throw an exception

* Note: This is a kind of a dirty way of finding out who's

* calling the method by using debug_backtrace and reflection

*/

$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);

if (isset($trace[2])) {

$ref = new ReflectionClass($trace[2]['class']);

if ($ref->isSubclassOf(__CLASS__)) {

return $this->$method($args);

}

}

throw new \Exception("Call to private method $class::$method()");

} else {

throw new \Exception("Call to undefined method $class::$method()");

}

}

}

}


回答:

namespace Package {

class MyParent extends \Package {

public $publicChild;

protected $protectedChild;

public function __construct() {

//instantiate public child inside parent

$this->publicChild = new \Package\MyParent\PublicChild();

//instantiate protected child inside parent

$this->protectedChild = new \Package\MyParent\ProtectedChild();

}

public function test() {

echo "Call from parent -> ";

$this->publicChild->protectedMethod();

$this->protectedChild->protectedMethod();

echo "<br>Siblings<br>";

$this->publicChild->callSibling($this->protectedChild);

}

}

}

namespace Package\MyParent

{

class PublicChild extends \Package {

//Makes the constructor public, hence callable from outside

public function __construct() {}

protected function protectedMethod() {

echo "I'm ".get_class($this)." protected method<br>";

}

protected function callSibling($sibling) {

echo "Call from " . get_class($this) . " -> ";

$sibling->protectedMethod();

}

}

class ProtectedChild extends \Package {

protected function protectedMethod() {

echo "I'm ".get_class($this)." protected method<br>";

}

protected function callSibling($sibling) {

echo "Call from " . get_class($this) . " -> ";

$sibling->protectedMethod();

}

}

}

回答:

$parent = new Package\MyParent();

$parent->test();

$pubChild = new Package\MyParent\PublicChild();//create new public child (possible)

$protChild = new Package\MyParent\ProtectedChild(); //create new protected child (ERROR)

输出:

Call from parent -> I'm Package protected method

I'm Package protected method

Siblings

Call from Package -> I'm Package protected method

Fatal error: Call to protected Package::__construct() from invalid context


回答:

我真的不认为尝试在PHP中模拟innerClasses是一个好主意。我认为代码不太清晰易读。另外,可能还有其他方法可以使用完善的模式来获得相似的结果,例如观察者,装饰或合并模式。有时,即使是简单的继承也已足够。

以上是 PHP中的嵌套或内部类 的全部内容, 来源链接: utcz.com/qa/433677.html

回到顶部