我正在尝试从无法更改的外部库中继承类(Y)。它有一个方法:
protected Object doSomething(Class<?> clazz)
现在在我的Scala类(X)中,我正在扩展此类并尝试覆盖该方法。
override protected def doSomething(clazz: Class[_ <: Object]): AnyRef
然而,这会导致&#39; Method doSomething覆盖任何内容&#39;。将代码更改为:
override protected def doSomething(clazz: Class[_]): AnyRef
停止此错误,但现在编译类时会导致以下错误:
class X needs to be abstract, since method doSomething in class Y of type (x$1: Class[_ <: Object])Object is not defined
(Note that Class[_ <: T] does not match Class[_]: their type parameters differ)
有没有办法实现这个目标? Scala版本:2.12.1,Java版本8.
答案 0 :(得分:2)
在这个问题中你没有提到Object doSomething(Class<?> clazz)
方法是抽象泛型类的abstract T doSomething(Class<? extends T> clazz)
方法的实现。
所以实际上你有以下Java类(为简洁我将doSomething
重命名为test
):
public abstract class AbstractJava<T> {
protected abstract T test(Class<? extends T> c);
}
public class ConcreteJava extends AbstractJava<Object> {
@Override
protected Object test(Class<?> c) {
return null;
}
}
您正在尝试实施以下Scala类:
class ConcreteScala extends ConcreteJava {
override protected def test(c: Class[_]) = super.test(c)
}
但编译失败,因为当您尝试覆盖test()
时,Scala会将ConcreteJava.test()
和AbstractJava.test()
方法视为具有不同的签名。
我找到了以下解决方法。
创建其他Java类,通过覆盖test()
“将其”重命名为renameTest()
,并提供通过ConcreteJava.test()
方法调用超级concreteTest()
的功能。
public abstract class RenameJava extends ConcreteJava {
public Object concreteTest(Class<?> c) {
return super.test(c);
}
abstract protected Object renameTest(Class<?> c);
@Override
protected Object test(Class<?> c) {
return renameTest(c);
}
}
现在在ConcreteScala
课程中,您可以覆盖renameTest()
,并且您仍然可以使用ConcreteJava.test()
方法调用超级concreteTest()
方法。
class ConcreteScala extends RenameJava {
override protected def renameTest(c: Class[_]) = {
// custom logic
concreteTest(c)
}
}
在您特定的“Spring”案例中,它以下列方式实现。
<强> RenameGsonHttpMessageConverter.java 强>
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import java.io.IOException;
public abstract class RenameGsonHttpMessageConverter extends GsonHttpMessageConverter {
protected Object superReadInternal(Class<?> clazz, HttpInputMessage inputMessage) throws
IOException, HttpMessageNotReadableException {
return super.readInternal(clazz, inputMessage);
}
abstract protected Object renameReadInternal(Class<?> clazz, HttpInputMessage inputMessage) throws
IOException, HttpMessageNotReadableException;
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return renameReadInternal(clazz, inputMessage);
}
}
<强> CustomGsonHttpMessageConverter.scala 强>
import org.springframework.http.HttpInputMessage
class CustomGsonHttpMessageConverter extends RenameGsonHttpMessageConverter {
override protected def renameReadInternal(clazz: Class[_], inputMessage: HttpInputMessage) = {
// custom logic
// or you may want to call
superReadInternal(clazz, inputMessage)
}
}
我还制作了一个错误报告SI-10155。