use*_*264 5 java inheritance casting
Hullo all,
想知道是否有任何Java黑客可以告诉我为什么以下不起作用:
public class Parent {
public Parent copy() {
Parent aCopy = new Parent();
...
return aCopy;
}
}
public class ChildN extends Parent {
...
}
public class Driver {
public static void main(String[] args) {
ChildN orig = new ChildN();
...
ChildN copy = orig.getClass().cast(orig.copy());
}
}
Run Code Online (Sandbox Code Playgroud)
代码很高兴编译,但决定在运行时D =抛出ClassCastException
编辑:哇,真的很快回复.多谢你们!所以我似乎无法使用这种方法向下转换...有没有其他方法可以在Java中进行向下转换?我确实考虑过让每个ChildN
类都覆盖copy()
,但是并不热衷于添加额外的样板代码.
就像试图这样做:
public Object copy(){
return new Object();
}
Run Code Online (Sandbox Code Playgroud)
然后尝试:
String s = ( String ) copy();
Run Code Online (Sandbox Code Playgroud)
您的Parent类和ChildN类与Object和String具有相同的关系
要使其工作,您需要执行以下操作:
public class ChildN extends Parent {
public Parent copy() {
return new ChildN();
}
}
Run Code Online (Sandbox Code Playgroud)
也就是说,覆盖"复制"方法并返回正确的实例.
根据你的编辑.这实际上是可能的.这可能是一种可能的方式:
public class Parent {
public Parent copy() {
Parent copy = this.getClass().newInstance();
//...
return copy;
}
}
Run Code Online (Sandbox Code Playgroud)
这样您就不必重写每个子类中的"copy"方法.这是Prototype设计模式.
但是,使用此实现,您应该知道两个已检查的异常.这是编译和运行没有问题的完整程序.
public class Parent {
public Parent copy() throws InstantiationException, IllegalAccessException {
Parent copy = this.getClass().newInstance();
//...
return copy;
}
}
class ChildN extends Parent {}
class Driver {
public static void main(String[] args) throws InstantiationException , IllegalAccessException {
ChildN orig = new ChildN();
ChildN copy = orig.getClass().cast(orig.copy());
System.out.println( "Greetings from : " + copy );
}
}
Run Code Online (Sandbox Code Playgroud)
演员有效地尝试这样做:
ChildN copy = (ChildN) orig.copy();
Run Code Online (Sandbox Code Playgroud)
(它的工作出在执行时间,执行转换,但是这会是因为什么orig.getClass()
会ChildN.class
),但orig.copy()
不会返回ChildN的实例,它返回的只是一个实例Parent
,所以它不能被转换为ChildN
.
(评论里无法添加代码,所以我在这里添加)
关于 Cloneable:如果您正在实现 Cloneable,请按如下方式实现;打电话更干净...
public class Foo implements Cloneable {
public Foo clone() {
try {
return (Foo) super.clone();
} catch (CloneNotSupportedException e) {
return null; // can never happen!
}
}
Run Code Online (Sandbox Code Playgroud)
[编辑:我也看到其他人使用
throw new AssertionError("This should never happen! I'm Cloneable!");
Run Code Online (Sandbox Code Playgroud)
在 catch 块中。]