我有以下情况:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(DerivedA deriv);
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new DerivedA.Something() {
@Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
我想将usefulMethod
和Something
推送到Base
类,以便DerivedB
可以利用它。我希望Something.doSomething
的实现能够使用派生类型,以便它可以访问派生的功能。
我该怎么做?
我尝试了以下内容:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(Base deriv);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something() {
@Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
但由于我的匿名Something
没有实施doSomething(Base)
,因此失败了。所以试图使用泛型:
我试过了:
interface Something {
void doSomething(<? extends Base> deriv);
}
但由于以下原因无法编译:“通配符只能用作参考参数”
我试过了:
interface Something {
<T extends Base> void doSomething(T deriv);
}
但这需要我实现接口:
a.usefulMethod(new Base.Something() {
@Override
public <T extends Base> void doSomething(T deriv) {
}
});
这显然不允许我访问派生类型?
有些方法可以使它“有效”,但它们是不受欢迎的:
此:
interface Something {
void doSomething(Base deriv);
}
a.usefulMethod(new Base.Something() {
@Override
public void doSomething(Base deriv) {
DerivedA a1 = (DerivedA) deriv;
a1.DerivedBMethodA();
}
});
但这需要我在每个实施中投下,这似乎很浪费。
而且:
package com.miurasample.ui.info;
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something<T extends Base> {
void doSomething(T deriv);
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something<DerivedA>() {
@Override
public void doSomething(DerivedA deriv) {
}
});
}
}
但是会导致usefulMethod
中的警告/ IDE突出显示:
“未选中调用doSomething(T)作为原始类型Base.Something
的成员”
最简洁,最“干净”的方法是什么?那我是在理智吗?
答案 0 :(得分:1)
很难说你的设计是否错误。我们没有足够的要求来断言,但这里是你想要做的干净的非铸造方法。它确实需要派生类中的额外方法:
public static void main(String... args) {
DerivedA a = new DerivedA();
a.usefulMethod( new Base.Something<DerivedA>() {
@Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
} );
}
public abstract static class Base< T extends Base<T> > {
int data = 0;
protected abstract T getThis();
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something<T> something) {
something.doSomething( getThis() );
}
interface Something< T extends Base<T> > {
void doSomething(T deriv);
}
}
public static class DerivedA extends Base<DerivedA> {
protected DerivedA getThis(){
return this;
}
void DerivedBMethodA() {}
}
public static class DerivedB extends Base<DerivedB> {
protected DerivedB getThis(){
return this;
}
void DerivedMethodB() {}
}