类和命名空间是啥关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类和命名空间是啥关系相关的知识,希望对你有一定的参考价值。

命名空间可以说是一个范围,而类是这个范围里的,你要引用类的时候,你就要先把这个命名空间引用进来,才能调用到这个类,当然你也可以把所有东西都写在一个命名空间里,但是这样子的话,就达不到复用的要求,并且整个程序的代码都会相当的乱 参考技术A 最明显的一个好处是把类放在命名空间内能方便调用甚至是其他应用程序的调用(使用命名空间加类名实现调用)。
我们一般在作程序的时候可以把类就放在工程里面。
那么,有个问题:我这个类写得很好,并且适用之后我要作的其他一些工程,这样就有个问题,调用起来很麻烦。
这样,我们就可以把它放在一个命名空间里面,方便我们之后在其他一写设计里面方便地调用它,不用在重复写作这样一个类、或者作copy/pate这样的无聊举动了。本回答被提问者采纳
参考技术B 简单点说,类就好像是一个概念,并不是实体,比如“人”。

对象是实例化类得到的,比如“张三”就是“人”的实例,是一个具体的人。

命名空间就好像是一个范围,你把类定义在这个范围里,以后就好引用。
参考技术C 类属于命名空间,不同的命名空间包含不同的类。 参考技术D 现有命名空间才能有类

在 PHP 中导入类和命名空间:前导反斜杠有啥区别?

【中文标题】在 PHP 中导入类和命名空间:前导反斜杠有啥区别?【英文标题】:Importing classes and namespaces in PHP: What difference does a leading backslash make?在 PHP 中导入类和命名空间:前导反斜杠有什么区别? 【发布时间】:2011-06-18 11:15:31 【问题描述】:

这两者有什么区别:

use Exception;
use \Exception;

或者那些:

use Foo\Bar;
use \Foo\Bar;

manual 说:

请注意,对于命名空间名称(完全 限定的命名空间名称包含 命名空间分隔符,例如 Foo\Bar 与全局名称相反 不是,如 FooBar),领先的 反斜杠是不必要的,而不是 允许,因为导入名称必须完全 合格,不予处理 相对于当前命名空间。

但我并不真正理解这一点,因为上述所有变体都有效,即它绝对不是“不允许的”。

查看zend_do_use 表明,is_global(设置,当有前导反斜杠时)仅在以下情况下用于警告:

namespace 
    use Exception;

这告诉我:“使用非复合名称 'Exception' 的语句无效”。 (尽管对use \Exception 执行相同操作会产生同样的影响,但不会引发警告。)

那么:我错过了什么吗?真的有区别吗?

【问题讨论】:

【参考方案1】:

手册将反斜杠指定为unnecessary,这自然意味着如果你还用它,意思是等价的。但是,正如您所指出的,手册上说它应该是不允许的,这是错误的。

但是,该手册还有其他问题。他们宣传这个:

// importing a global class
use \ArrayObject;

如果确实没有相对于当前命名空间处理导入名称,那么use \ArrayObjectuse ArrayObject 必须具有相同的含义。除了全局之外,use ArrayObject 还能指代什么?在实践中,引擎将导入全局引擎。

此外,还有以下错误: http://bugs.php.net/bug.php?id=49143

我认为对于标准应该是什么存在混淆。

回答您的问题:没有区别。但是,如果我是引擎开发人员,也是无前导斜线标准的信徒,那么我就不需要考虑有人写use \Exception; 的情况。我相信很可能就是这种情况。

【讨论】:

请注意,如果是命名空间类,您使用 composer 加载一个类,只需通过其“姓氏”名称(无命名空间前缀)调用它,如果您不是,则使用 MUST 前缀和反斜杠将在使用之前调用它。示例:\QuantumPHP::log("some message");除非您添加“使用 QuantumPHP;”在类定义之前。【参考方案2】:

事实上,目前在导入命名空间时使用前导反斜杠没有区别,PHP manual 中的信息也发生了变化:

请注意,对于命名空间名称(完全限定的命名空间名称 包含命名空间分隔符,例如 Foo\Bar 而不是全局 没有的名称,例如 FooBar),前导反斜杠是 不必要且不推荐,因为导入名称必须完整 限定,并且不相对于当前命名空间进行处理。

所以现在有真实信息表明不建议使用前导反斜杠,但没有信息表明过去是不允许的。

所以现在:

use Exception;
use \Exception;

这两行是一样的,但你应该使用第一行。

【讨论】:

【参考方案3】:

通常前导反斜杠定义标识符是绝对的。如果它缺失,解释器假定它是一个相对标识符。

这是一个绝对标识符:

$x = new \Name\Space\To\Class();

这是一个相对标识符,因为没有前导斜杠。它是相对于当前命名空间的:

namespace Name\Space;
$x = new To\Class;

这也是一个相对标识符。在这种情况下,它针对use 语句解决,因为最后一部分(别名)与类的第一部分相同:

namespace Other\Name\Space;
use Name\Space;
$x = new Space\To\Class;

但是,因为在namespaceuse 语句中只允许使用绝对标识符(完全限定名称),所以这里可以省略它。在namespace中,甚至不允许设置前导反斜杠。

有关 PHP 如何解析不同命名空间声明的更多信息,请参阅namespace rules manual。

【讨论】:

【参考方案4】:

前导反斜杠表示全局命名空间。如果您在命名空间的范围内,则必须使用它来访问全局命名空间。例如:

namespace A

    class A
    
        public function __construct()
        
            echo('namespace: A<br />');
        
    


namespace B\A

    class A
    
        public function __construct()
        
            echo('namespace: B\\A<br />');
        
    


namespace B

    class B
    
        public function __construct()
        
            new \A\A(); // namespace: A
            new A\A(); // namespace: B\A
        
    
    new B();

使用前导反斜杠获得绝对路径,没有反斜杠则获得相对路径。

【讨论】:

这是我见过的最令人困惑的例子。 顺便说一句。我写的时候没有“use”关键字。带有“A”类的“B\A”命名空间是一个有趣的选择。 :D 我在变量命名方面很有天赋... :D【参考方案5】:

别说我们有

namespace MyNamespace
use Exception;
use \Exception;

那么第一次使用实际上导入类 MyNamespace\Exception 而第二个只是主类 \Exception

所以你可以有类似的东西

namespace MyNamespace;
class Exception extends \Exception 

然后我可以

throw new \Exception('Exception from global namespace');
throw new \MyNamespace\Exception('Exception from MyNamespace');

【讨论】:

namespace Foo class Exception extends \Exception use Exception as BigFoo; throw new BigFoo; 这会抛出全局 Exception,而不是本地的。上面链接的文档也说:“导入名称必须是完全限定的,并且不相对于当前命名空间进行处理”。 错了。 use-语句始终使用全限定名。因此use Exception; 不会针对当前命名空间进行解析,实际上与use \Exception; 相同。

以上是关于类和命名空间是啥关系的主要内容,如果未能解决你的问题,请参考以下文章

JSDoc:模块和命名空间之间的关系是啥

Python中的命名空间是啥?

“Model”是“命名空间”,但此处被当做“类型”来使用,是啥原因导致的哦,这段代码我写

类和对象的命名空间

Aerospike 中的命名空间是啥

C#命名空间与类和方法的认识