java中的向上转换
在Java中,假设我有3个类,C从B扩展而来,B从A扩展而来java中的向上转换,java,casting,Java,Casting,在Java中,假设我有3个类,C从B扩展而来,B从A扩展而来 class X { interface A {} interface B extends A {} interface C extends B {} void f(A a) {} void test() { C c = new C() B b = (B) c; f(b); } } 如果我这样做,如上面的test()所示: C c = new C() B b
class X {
interface A {}
interface B extends A {}
interface C extends B {}
void f(A a) {}
void test() {
C c = new C()
B b = (B) c;
f(b);
}
}
如果我这样做,如上面的test()
所示:
C c = new C()
B b = (B) c;
f(b);
f()
接受b
作为类型C
,因为C
和b
都是从A
扩展而来的。我希望f()
接收b
类型b
而不是类型C
还有什么办法强迫这种向上转换吗?f()
将始终接收键入为A的内容(尽管在封面下它实际上是A B或C,并且可以适当地向下转换)
您可以这样定义一个附加的f()
如果有必要
f(C c);
根据参数的类别,将调用正确的参数。i、 编译器根据参数的类型确定调用哪个函数。这与运行时发生的动态调度(或多态性)不同
请注意,您在问题中的角色是多余的。你可以写:
C c = new C()
B b = c;
f(b);
因为C是从B扩展而来的,所以C是B
我希望f接收b类型的b,而不是C类型的
AC
是AB
是AA
在f
内部,f
只看到其参数A
的A
部分,如果f
调用在C
中被重写的公共A
函数,则调用C
重写
这就是虚拟函数的工作原理。这个想法是,所指的对象实际上是一个C
,因此它应该表现出C
行为。如果想要B
行为,请传递B
实例,而不是C
实例
如果“C”和“B”应该具有相同的行为,请不要在C
中验证该行为
你为什么要这样做?你的问题毫无意义。你说的“f接受b为C型”是什么意思 f接受b作为类型A,因为方法签名是“A”。如果在b上调用方法,如果C重写它们,它们将在C上被调用。但这是Java中的标准行为(所有方法都类似于C++中的虚拟方法),无法更改
也许您可以描述您的实际问题,然后我们可能会提供帮助。您似乎对编译时类型和运行时类型之间的差异感到困惑 您正在创建类型为c的对象(由引用c和b指向),它将保持为c,因为不可能更改对象的运行时类型和行为;通过强制转换,您只能更改其编译时类型,这会影响编译器如何处理它
你能提供一些关于你试图解决的具体问题的更多信息吗?很可能有一种方法可以通过改变设计来实现你的目标。事实上,你可以将a的任何子类作为f(a)的参数传递是Java中OO固有的,您无法绕过此问题。如果C扩展了A,则始终可以在需要A的地方使用它。您可以使用反射来检查参数是否属于A类:
public void f(A a) {
if (a.getClass() == A.class) {
// ok, go on
}
else {
System.err.println("The parameter is not of class A!");
}
}
不知道这是否是您想要的,但可能会有所帮助。您的问题可以通过理解引用类型和实例类型之间的差异来解决。当您将C对象强制转换为B时,您只需更改引用类型-对象的实际实例仍然是C对象-如果您查看ob,这一点应该非常明显对象处于调试模式。更改引用类型仅影响编译器处理/感知代码的方式-不应影响运行时行为。对C对象的任何方法调用都将始终调用C的方法(无论该对象是否已强制转换为其他对象)。如果您对B中的方法进行了过度编码,并希望调用B版本的方法,则需要创建B实例。事实上,您的代码引用了a,但这并不意味着指向的对象也是a。如果是a C,则仍然是C。源代码中的引用仅限制了源代码中可用的方法。强制转换仅为n这是必要的,因为有时需要在不同类型上使用方法,我们需要欺骗编译器,所以让我们开始在类型上使用方法。如果尝试无效,则在运行时强制转换自然会失败。这正是我试图理解的。我希望参数显示B行为。我想我必须创建一个新的在将参数传递给f之前,请从C中调用B实例。谢谢。如果希望f对B进行操作,为什么不创建一个B?C从何而来?我希望f根据其类型调用参数的方法,因此如果参数是C,我希望调用C.deliverTo(),但如果参数是B,我希望调用B.deliverTo()。谢谢。是的,还有另一种方法可以完成我想要的任务,我可以从a C创建B的新实例,但我想了解为什么我不能用我第一次尝试的方法来完成:)谢谢。
In upcasting and downcasting the object first upcast then downcastenter
class A
{
}
class B extends A
{
}
Class M
{
psvm(String ar[])
{
A a1= new B();
B b2=(B)a1;
}
In upcasting and downcasting the object first upcast then downcastenter
class A
{
}
class B extends A
{
}
Class M
{
psvm(String ar[])
{
A a1= new B();
B b2=(B)a1;
}