2009-10-26 184 views
11

的返回类型,我有以下情况:Java泛型执行抽象方法

abstract class X { abstract X someMethod (...) {...} }. 

现在我想约束X的任何实施有它“的someMethod”方法返回一个特定的实现类型,而不仅仅是X :

class X1 extends X { X1 someMethod (...) {...} }. 
class X1 extends X { X someMethod (...) {...} }. //want this to be flagged as an error 
class X2 extends X { X1 someMethod (...) {...} }. //want this to be flagged as an error too 

使用Java泛型可以达到这个目的吗?

编辑

好的。我只问了是/否问题并得到了“是”。我的错。我真正感兴趣的是“我如何撰写声明”。

回答

17

这也适用;

abstract class X<T> { 
    public abstract T yourMethod(); 
} 
class X1 extends X<X1> { 
    public X1 yourMethod() { 
     return this; 
    } 
} 
class X2 extends X<X2> { 
    public X2 yourMethod() { 
     return this; 
    } 
} 
+5

我认为这是非常丑陋的代码,但它也是我所知道的唯一解决方案,并且我自己使用它自己... +1 – rmeador 2009-10-26 22:56:54

+0

第二个想法......有人确实知道这是一个功能Jav – 2009-10-26 23:03:48

+0

... Java泛型的特征,而不仅仅是它们构思/实现方式的危险副产品? – 2009-10-26 23:04:35

0

这应该只是罚款:

class X<T> { 
    abstract T someMethod(...); 
} 

class X1<T1> extends X 
    T1 someMethod(...) { 
    ... 
    } 
} 
4
abstract class X<I extends X<I>> { 
    protected X(Class<I> implClazz) { 
     if (!getClass().equals(implClazz)) { 
      throw new IllegalArgumentException(); 
     } 
    } 

    abstract I someMethod(); 
} 

理由:你不能指动态类型的类型限制,因此间接检查在构造函数中。

+0

非常感谢,非常有帮助。 本来有投票权,但我得到一个“请登录或注册”的回复。 – 2009-10-26 22:47:24

+0

您的理由为什么比约恩的解决方案仍然允许我写 “class X2 extends X {X1 someMethod(){...}}” – 2009-10-26 23:16:45

+0

准确地说。构造函数的唯一目的是防止这种情况。 – meriton 2009-10-26 23:47:07

2

这里是一个可以让你对this返回的参数类型的方法:

AbstractFoo<T extends AbstractFoo<T>> { 
    /** Subclasses must implement to return {@code this}. */ 
    protected abstract T getThis(); 

    /** Does something interesting and returns this Foo */ 
    public T inheritedThing { 
    /* blah di blah */ 
    return getThis(); 
    } 
}