我很难继承一个非常简单的类,它有返回初始类的方法。
WDS.sampleResult.sampleStart()
WDS.browser.get('http://jmeter-plugins.org')
var jmeterLogo = WDS.browser.findElement(org.openqa.selenium.By.xpath("//img[@alt='Apache JMeter']"))
var actions = new org.openqa.selenium.interactions.Actions(WDS.browser)
actions.moveToElement(jmeterLogo).doubleClick().perform()
WDS.sampleResult.sampleEnd()
好的,现在如果我想打个电话:
public class MyClass {
public MyClass(){
}
public MyClass filterOn(String something){
MyClass result=new MyClass();
result.doSomethingUsingThisInstance(this, something);
return result;
}
}
public class MySubClass extends MyClass{
....
}
然后我有一个 java.lang.ClassCastException:无法将MyClass转换为MySubClass
如何防止这种情况?
答案 0 :(得分:2)
重写filterOn()
方法以在MySubClass
中创建您想要的实例:
public class MySubClass extends MyClass{
public MyClass filterOn(String something){
MySubClass result = new MySubClass();
result.doSomethingUsingThisInstance(this, something);
return result;
}
....
}
您还可以通过在filterOn()
中引入一个方法来创建我们在子类中重写的当前类的实例,从而避免MyClass
方法中的重复:
public class MyClass {
public MyClass(){
}
public MyClass createSpecificInstance() {
return new MyClass();
}
public MyClass filterOn(String something){
MyClass result = createSpecificInstance();
result.doSomethingUsingThisInstance(this, something);
return result;
}
}
现在Sub类只覆盖createSpecificInstance():
public class MySubClass extends MyClass {
public MyClass createSpecificInstance() {
return new MySubClass();
}
}
答案 1 :(得分:0)
(MySubClass)subClass.filterOn("Hello World");
和
public MyClass filterOn(String something)
您无法将基类强制转换为派生类。如果你这样做,你会得到那个例外, ClassCastException
答案 2 :(得分:0)
您尝试将返回值强制转换为派生类型,该类型不起作用并导致类强制转换异常。
原因:在类型层次结构中向上强制转换是有效的,因为您的基类只需要派生类(通常)具有的属性/方法。反过来不起作用,因为它可能导致问题。考虑:
class Base {
// some stuff here
}
class Derived1 extends Base {
private int foo;
}
class Derived2 extends Base {
private String bar;
}
Base myObject = new Derived1();
// this works, Derived1 has everything Base requires
// myObject.foo still exists, but can not be trivially accessed.
Derived2 myOtherObject = (Derived2)myObject;
// Now what?
// What happens to myObject.foo?
// Where does myOtherObject.bar come from?
在您的情况下,您可以做些什么:
filterOn()
的实现根据派生类的具体实现而有很大差异,请在基类中将其设为 abstract ,并在派生类中重新实现它。 / LI>
filterOn()
的结果转换为派生类吗?filterOn()
的实现完全相同(当然类型除外)。Derived1(Base baseObject){
// copy all the stuff from the base object
this.foo = 0; // initialize the rest
}
class BetterThenDerived {
private Base myBaseObject;
private int foo;
}
答案 3 :(得分:0)
这是协方差问题的一个方面。请参阅示例Covariance and contravariance。并且Demonstrate covariance and contravariance in Java?。这不是Java擅长的地方,但有几个选择。
首先,在覆盖方法时,您可以声明更具体的返回类型。例如,在MySubClass
中,您可以声明:
@Override
public MySubClass filterOn(String something) {
// ...
}
现在这不能解决您的问题。您仍然需要一种方法来为此方法创建并对MySubClass
对象执行某些操作。它做了什么,它使客户端代码免于需要演员表。您可以从davidxxx的答案中获取方法的实现(假设result.doSomethingUsingThisInstance()
为protected
或public
):
@Override
public MySubClass filterOn(String something) {
MySubClass result = new MySubClass();
result.doSomethingUsingThisInstance(this, something);
return result;
}
您可能不得不在所有子类中复制此方法。如果真实工作留在result.doSomethingUsingThisInstance()
,我认为你可以忍受它。
另一个想法是clone()
用于生成正确运行时类型的对象:
public class MyClass implements Cloneable {
public MyClass filterOn(String something) {
try {
MyClass result = (MyClass) this.clone();
result.doSomethingUsingThisInstance(this, something);
return result;
} catch (CloneNotSupportedException cnse) {
throw new AssertionError(cnse);
}
}
}
但是,在使用这个想法之前,我会三思而后行。您的克隆包含您不希望存在的数据的一个原因,因此您可能必须确保在克隆之前清除它。您仍然可以将它与返回子类中的特定子类型结合起来,现在它只需要一个强制转换(仍然在实现中,客户端不需要担心):
public class MySubClass extends MyClass {
@Override
public MySubClass filterOn(String something) {
return (MySubClass) super.filterOn(something);
}
}