将对象投射到接口 [英] Casting an Object to an Interface

查看:54
本文介绍了将对象投射到接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下类和接口:

public interface if1 {}
public class ifTest implements if1 {}

public class HelloWorld {
     public static void main(String[] args) {
          //why does the following cast not work (Compiler error)  
          ifTest var3 = (if1) new ifTest();
     }
}

为什么这个强制转换不起作用?我收到以下编译错误:类型不匹配:无法从if1转换为ifTest"

Why does this cast not work? I get the following compile error: "Type mismatch: cannot convert from if1 to ifTest"

推荐答案

继承表示 is-a 关系. IfTest 的任何对象都是 If1 .但是,对 If1 类型的引用不一定引用对 IfTest 类型的对象.

Inheritance denotes an is-a relationship. Any object of IfTest is-an If1. However, a reference of type If1 does not necessarily refer to an object of type IfTest.

在教科书中,任何 Dog 都是 Animal ,但任何 Animal 都不是 Dog (它是可能是斑马,大象,鹿等).

In a textbook scenario, any Dog is an Animal but any Animal is not a Dog (it might be a zebra, elephant, deer, etc).

铸造采用以下形式:

A a = (B) c;

涉及2个步骤:

  1. 您有任何强制转换为 B 类型的对象 c .
  2. 然后将那个 B 的实例分配给变量 a (其中 A 是必须等于 B的类型 B 的超类,以使编译器满意并且在运行时不会发生 ClassCastExceptions .
  1. You have any object c that is cast to type B.
  2. That instance of B is then assigned to variable a (where A is a type that must be either equal to B or a super class of B for the compiler to be happy and for no ClassCastExceptions to occur at runtime.

继续动物隐喻,您将在步骤1中将 Dog 投射到 Animal ,然后尝试分配该 Animal 实例到 Dog 类型的变量,编译器知道这是不允许的.

Continuing the animal metaphor, you are casting Dog to an Animal in step 1, but then trying to assign that instance of an Animal to a variable of type Dog, which the compiler knows is not allowed.

以下内容将起作用,因为它将 IfTest 强制转换为 If1 ,然后将该 If1 分配给 IfTest ./p>

The following would work because it casts IfTest to If1 and then assigning that If1 to IfTest.

if1 var3 = (if1) new ifTest();

编辑正如Lew在下面的评论中所指出的,这就是所谓的扩大类型转换(因为它从特定类型变为更通用的更广泛"类型.)例如,强制类型转换不是必需的,因为编译器根据定义知道对 IfTest 类型的对象的所有引用也都是 If1 .

EDIT As Lew points out in his comment below, this is what is referred to as a widening cast (because it goes from a specific type to a more generic, "wider" type. In this instance, the cast is not necessary because the compiler knows all references to objects of type IfTest by definition are also If1.

一个更实际的示例是,如果您具有对该接口的引用,并希望将其强制转换为 IfTest .在这种情况下,这是缩小"强制转换,因为您将从通用类型转换为更具体的缩小"类型.

A more practical example would be if you had a reference to the interface and wanted to cast it to a IfTest. In this case, it's a "narrowing" cast because you're going from the generic type to a more specific, "narrower" type.

if1 var1 = (if1) new ifTest();
if (var1 instanceOf ifTest) {
    ifTest var2 = (ifTest) var1;
}

请注意使用 instanceof 来确保 var1 实际上是 IfTest 的实例.众所周知,在实际应用程序中, If1 可能具有多个子类型,因此并非总是如此.该检查可防止强制转换引发运行时 ClassCassException .

Note the use of the instanceof to to ensure that var1 is in fact an instance of IfTest. While we know it is, in a real-world application If1 might have multiple subtypes so this will not always be true. The check prevents the cast from throwing a run-time ClassCassException.

TLDR :要知道的重要一点是,括号内的内容必须是编译器知道的可以分配给要分配给该变量的类型.

TLDR: The important thing to know is what is inside the parenthesis must be a type the compiler knows can be assigned to the variable being assigned to.

这篇关于将对象投射到接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆