我正在为新网站构建 用户类 ,但是这次我在考虑构建它有点不同…
C ++ , Java 甚至 Ruby
(可能还有其他编程语言)都允许在主类内部使用嵌套/内部类,这使我们可以使代码更加面向对象和组织化。
在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是一个好主意。我认为代码不太清晰易读。另外,可能还有其他方法可以使用完善的模式来获得相似的结果,例如观察者,装饰或合并模式。有时,即使是简单的继承也已足够。
Oracle留档(在下面的链接)说: 非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有的。 但在下面的示例中,我创建了一个对象(内部类),它无法访问其封闭外部类的任何方法或变量。下面是代码,你能解释一下吗? http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html 使用Main方法初始化 对于对象,我无法访问其
问题内容: Go支持在函数内部嵌套结构,但除了lambda之外没有嵌套函数,这是否意味着无法在函数内部定义嵌套类? 因此,类在函数内部被削弱感到有点奇怪。 有什么提示吗? 问题答案: 实际上,无论您要声明 带有 接收器还是 不 带有接收器的函数都没有关系:不允许在Go中嵌套函数。 尽管您可以使用函数文字来实现以下目的: 在这里,我们创建了一个具有函数类型的变量,并将其分配给另一个函数。调用“外部”
问题内容: 我必须与API进行交互,并且响应格式(根据我的阅读)似乎结构不良。我发现一个Google 网上论坛在这里回答了一个类似的问题,但是我在实现Response类来处理Gson.fromJson时遇到了麻烦。有没有我想念的例子? 问题答案: JSON对象可以由或Javabean类表示。这是一个使用Javabean的示例。 如下使用它:
我试图制作一个for循环脚本,使用Angular创建订单,并将其添加到网页中。我在使用某些for循环时遇到了问题,因为当我使用控制台时。log(),它只输出外部循环,不输出内部循环。我需要把变量的顺序传递给另一个函数,所以我需要这个顺序来获得正确的数据。 结果: 它重复最后一个外环值,而不输出内环值。我对Javascript还是很陌生的,所以我需要一些洞察力和解决方案,也许还有简单的方法?谢谢!
问题内容: 我需要在QueryDsl Native MySQL中运行以下查询。 上面的查询具有嵌套的3个mysql函数,例如cast,json_unquote和json_extract。在QueryDsl中,我为每个函数创建了单独的表达式,如下面的代码所示。 我必须创建更多数量的表达式,而不要创建更多的函数。为了降低复杂性,是否可以在单个表达式中调用多个函数? 问题答案: 我找到了问题的答案。 感
问题内容: 我在论坛上进行了搜索,但没有得到权威的答案。我想以这种方式实现嵌套的注释结构: 我的表的转储如下: 我知道如何使用和循环。PHP和MySQL的新手。请帮帮我。 问题答案: 我在博客文章中做了类似的事情。但是,我只是尝试了相同的数据。当您说 嵌套注释时 ,最好以这种方式使用 嵌套函数 : 为此,我已将您的数据导入MySQL并尝试了以下操作: 就像我之前说过的那样,我使用了嵌套函数,并且正