也许这种方法是错误的。我的想法如下:
public abstract AbstractParser<T extends Value> {
T value;
//want to do something like
public abstract void parseSomething(Model model) {
value = (T) model.getValue()
}
}
然后我希望每个子类都重写parseSomething而不丢失该默认行为。因此,当子项覆盖parseSomething时,它将具有 value 的正确实现。
public ConcreteParser extends AbstractParser<ConcreteValue> {
//now in Value I have a ConcreteValue to access
@Override
public void parseSomething(Model model) {
//here I want to do stuff with value without having to do:
value = (ConcreteValue) model.getValue();
//in every implementation I create
}
}
有什么想法吗?
答案 0 :(得分:1)
缺少的第一个,您需要Class<T>
才能强制转换为T
(类型擦除)。 (如果模型不可参数化。)
对于这个问题,有一个很好的解决方案,
parseSomething
; 可覆盖的方法在最终的public方法中被调用,并且可以具有更多的参数,例如value。该方法可以是abstract
。
所以:
public abstract AbstractParser<T extends Value> {
private final Class<T> valueType;
protected T value;
protected AbstractParser(Class<T> valueType) {
this.valueType = valueType;
}
// Class users will call this method
public final void parseSomething(Model model) {
value = valueType.cast(model.getValue());
onParseSomething(model, value);
}
// Class implementors will override/implement this method
protected void onParseSomething(Model model, T value) {
}
}
public ConcreteParser extends AbstractParser<ConcreteValue> {
public ConcreteParser() {
super(ConcreteValue.class);
}
@Override
public void onParseSomething(Model model, ConcreteValue value) {
}
}
答案 1 :(得分:0)
是的,甚至从Java 8开始扩展到接口:
public interface IExample {
default public String test() {
return " world!";
}
}
public class Example implements IExample {
@Override
public String test() {
return "Hello " + IExample.super.test();
}
}
要引用父接口的超级方法,还必须在super
之前包括类名称。最终结果:
System.out.println(new Example().test());
//Hello world!
从语义上讲,如果您想保护特定父方法的功能,并且让子类仅定义行为的一个子集,请考虑使用面向公众的方法,以及用于定义行为子集的受保护方法:>
public abstract class AbstractParser<T extends Value> {
protected T value;
//final, cannot be overridden
public final void parseSomething(Model model) {
this.value = (T) model.getValue();
this.continueParsing();
}
protected abstract void continueParsing();
}
public class ConcreteParser extends AbstractParser<ConcreteValue> {
@Override
protected void continueParsing() {
//invoked after the value `T` is set by the public method
//references to `this.value` will be of type `T` or in this case, `ConcreteValue`
}
}
答案 2 :(得分:0)
您要查找的内容只能通过泛型来实现。
可以Model
类进行参数化:
class Model<T> {
...
T getValue();
...
}
然后AbstractParser
类可以重写为:
abstract class AbstractParser<T> {
T value;
public abstract void parseSomething(final Model<T> model) {
this.value = model.getValue();
}
}
由于在使用前已初始化value
的保证,因此可以通过构造函数注入将类重写为不可变的。
abstract class AbstractParser<T> {
final T value;
AbstractParser(final Model<T> model) {
this.value = model.getValue();
}
...
}
答案 3 :(得分:0)
这将为您做到:
public ConcreteParser extends AbstractParser<ConcreteValue> {
@Override
public void parseSomething(Model model) {
if(!(model instanceOf ConcreteValue)) // to ensure safety
return;
//do what ever you like first, this.value is null by far if
//this method is getting called the 1st time
super.parseSomething(model);
// now you can use value as you like from here on.
}
}