当前位置: 首页 > 面试题库 >

用户定义对象的类型转换

宰烈
2023-03-14
问题内容

就像我们使用__ToString一样,有没有一种方法来定义铸造方法

$obj = (MyClass) $another_class_obj;

问题答案:

无需在php中键入强制类型转换。

编辑: 由于这个话题似乎引起一些混乱,我想我要详细说明一下。

在Java之类的语言中,有两种可能带有类型。编译器有一个关于类型的概念,而运行时还有一个关于类型的想法。编译器的类型与变量相关,而运行时引擎则跟踪值的类型(已将其分配给变量)。变量类型在编译时是已知的,而值类型仅在运行时是已知的。

如果一段输入代码违反了编译器类型系统,则编译器将禁止并暂停编译。换句话说,不可能编译违反静态类型系统的代码。这捕获了某些类型的错误。例如,采用以下(简化的)Java代码:

class Alpha {}

class Beta extends Alpha {
  public void sayHello() {
    System.out.println("Hello");
  }
}

如果我们现在这样做:

Alpha a = new Beta();

我们很好,因为它Beta是的子类Alpha,因此是atype 变量的有效值Alpha。但是,如果我们继续这样做:

a.sayHello();

由于该方法sayHello不是有效的方法,因此编译器会给出错误消息Alpha-尽管我们知道这a实际上是一个Beta

输入类型转换:

((Beta) a).sayHello();

在这里,我们告诉编译器,a在这种情况下,应将变量视为Beta。这称为类型转换。这个漏洞非常有用,因为它允许语言中的多态,但是很明显,它还是各种违反类型系统的后门。为了保持某种类型的安全性,因此存在一些限制。您只能转换为相关的类型。例如。向上或向下的层次结构。换句话说,您将无法转换为完全不相关的类Charlie

重要的是要注意,所有这些都发生在编译器中-也就是说,它发生在代码运行之前。Java仍然可以进入运行时类型错误。例如,如果您这样做:

class Alpha {}

class Beta extends Alpha {
  public void sayHello() {
    System.out.println("Hello");
  }
}

class Charlie extends Alpha {}

Alpha a = new Charlie();
((Beta) a).sayHello();

上面的代码对编译器有效,但是在运行时,您会遇到异常,因为从BetaCharlie的转换不兼容。

同时,回到PHP农场。

以下内容对PHP编译器有效-它将很高兴将其转换为可执行字节代码,但您会遇到运行时错误:

class Alpha {}

class Beta extends Alpha {
  function sayHello() {
    print "Hello";
  }
}
$a = new Alpha();
$a->sayHello();

这是因为PHP变量没有类型。编译器不知道哪种运行时类型对变量有效,因此它不会尝试强制执行。您也不像在Java中那样显式地指定类型。有类型提示,是的,但是这些只是运行时合同。以下内容仍然有效:

// reuse the classes from above
function tellToSayHello(Alpha $a) {
  $a->sayHello();
}
tellToSayHello(new Beta());

即使PHP 变量 没有类型, 仍然是类型。PHP的一个特别有趣的方面是,可以更改值的类型。例如:

// The variable $foo holds a value with the type of string
$foo = "42";
echo gettype($foo); // Yields "string"
// Here we change the type from string -> integer
settype($foo, "integer");
echo gettype($foo); // Yields "integer"

此功能有时会与类型转换混淆,但这是用词不当。类型仍然是值的属性,类型更改在运行时发生-而不是在编译时发生。

在PHP中更改类型的能力也很有限。只能在简单类型之间更改类型-
不能在对象之间进行更改。因此,不可能将类型从一类更改为另一类。您可以创建一个新对象并复制状态,但是不能更改类型。在这方面,PHP有点局外人。其他类似的语言将类视为比PHP更动态的概念。

PHP的另一个类似功能是您可以将值克隆为新类型,如下所示:

// The variable $foo holds a value with the type of string
$foo = "42";
echo gettype($foo); // Yields "string"
// Here we change the type from string -> integer
$bar = (integer) $foo;
echo gettype($bar); // Yields "integer"

从语法上看,这很像是如何使用静态类型的语言编写类型转换的。因此,即使它仍然是运行时类型转换,也经常将其与类型转换混淆。

总结一下: 类型转换是一种更改变量类型( 而不是 值)的操作。由于变量在PHP中没有类型,因此不仅要做不到,而且首先要问的是荒谬的事情。



 类似资料:
  • 主要内容:1.底层的转换接口,2.高层的转换接口,3.演示高级接口类型转化,4.Spring中是如何操作泛型参数的,5.ConversionService扩展和@InitBinder扩展1.底层的转换接口 Spring提供的接口 Printer: 其他类型转为String Parser: String转为其他类型 Formatter: Printer + Parser Converter: 类型S转为类型T Printer, Parser, Converter通过适配转换为GenericConv

  • 问题内容: 所以我有一堂课,叫做。 我想打印此类的对象列表,如下所示: 但是它显示了这样的输出: 实际上,我想打印每个对象的值。有什么办法吗? 问题答案: 如果只想为每个对象打印标签,则可以使用循环或列表理解: 但是要回答您的原始问题,您需要定义方法以正确获得列表输出。它可能像这样简单:

  • 问题内容: 我得到错误: 我确信这是一个已知的范例,因为这似乎是一个非常常见的分层类使用问题(一个自引用类)。我知道我可以将be的类型更改为有效,但是这样做似乎是错误的事情,主要是因为它削弱了我检查呼叫类型的能力。随着改变是一种类型的我得到正确的结果: 我愿意考虑和提出建议。做这种事情的最“ pythonic”方法是什么? PS:这种“自我引用类”范式/问题的名称是什么,我可以用它来查找其他建议吗

  • 颜色选取器 在 1.受保护的无效上创建(捆绑保存实例状态) { 超级.on创建(已保存实例状态); 错误:创建(捆绑包)上的方法未定义对象 类型2.new MyView(指画活动.this); 错误:构造函数指画活动.MyView(指画活动)未定义 3.set内容查看(mv); 错误:他的方法集内容视图(指画活动.MyView)是未定义的类型指画活动 4.公共布尔值在创建选项菜单(菜单菜单) {

  • 如果我使用一个,其中键是定义类的对象,那么HashMap还会提供O(1)性能吗? 我认为它不应该给O(1)性能,因为用户定义对象的哈希键只返回键的地址,所以会有更多的冲突。

  • 主要内容:强制对象类型转换将一个类型强制转换成另一个类型的过程被称为类型转换。本节所说的 对象类型转换,是指存在继承关系的对象,不是任意类型的对象。当对不存在继承关系的对象进行强制类型转换时,会抛出 Java 强制类型转换(java.lang.ClassCastException)异常。 Java 语言允许某个类型的引用变量引用子类的实例,而且可以对这个引用变量进行类型转换。Java 中引用类型之间的类型转换(前提是两个类