2013-08-26 17 views
7

我想创建这两个类的通用接口,但我不知道如何以正确的方式指定泛型。创建通用接口限于自己的类

public class ThingA implements Thing { 
    public ThingA createCopy(ThingA original); 
} 

public class ThingB implements Thing { 
    public ThingB createCopy(ThingB original); 
} 

我试过了。

public interface Thing<V extends Thing<V>> { 
    public V createCopy(V original); 

} 

但我仍然可以做这样的事情,这是不应该被允许的。

public class ThingB implements Thing<ThingA> { 
    public ThingA createCopy(ThingA original); 
} 

回答

6

没有this关键字泛型(也不适用于方法参数和返回值声明),因此您不能完全按照您的要求进行操作。

换句话说,接口将允许确保类中的所有方法使用一致的类型,但不能引用类类型本身。

0

您是否在寻找

public interface Thing<V> { 
    public V createCopy(V original); 
} 

?如果不是,你能否更详细地解释一下“为两个类创建通用接口”对你意味着什么?

+1

这仍然可以让他做到他不想做的事。泛型不会阻止您仅使用一种类型的类,因为这将与泛型相反。 – giorashc

1

这是不可能的。这不是泛型的用途。泛型适用于型安全,即避免铸造。如果某人制作了一个ThingB类,以某种方式实现Thing<ThingA>,那么很好。这是完全类型安全的。你为什么在乎?它如何妨碍你在做什么?

0

如果您可以自由使用扩展,而不是执行,那么你可以做的是这样的:

public interface Thing { ... } 
public abstract class Copyable { 
    public final Copyable copy() { 
     Copyable clone = createCopy(); 
     if (clone.getClass() != getClass()) 
      throw new RuntimeException("Copy has wrong type!"); 
     return clone; 
    } 
    protected abstract Copyable createCopy(); 
} 

,然后用它喜欢:

public class Test extends Copyable implements Thing { 
    public String content = null; 

    @Override 
    public Copyable createCopy() { 
     Test clone = new Test(); 
     clone.content = this.content; 
     return clone; 
    } 
} 

/*code somewhere*/ { 
    Test t1 = new Test(); 
    t1.content = "Hello world!"; 
    Test t2 = (Test)t1.copy(); 
    System.out.println(t2.content); 
} 

一个这样的问题,是那Copyable不是一个接口。但是,如示例中所示,可以毫不费力地使用此类语句,但语言级别不支持使用的类检查。换句话说,createCopy抽象方法并不局限于它所复制的类,所有这一切都取决于扩展类的程序员或扩展它的类。

积极的一面是,如果您在对象上调用.copy(),它必须返回一个与它自己相同的对象。如果您愿意,您可以返回null而不是例外情况。然后你得到好或没有

但是,老实说,我不是很懂,为什么你的createCopy本地方法有一个参数。 这可能是再一个静态方法...... altrough我甚至无法想象会进入该代码块:

static <X extends Thing> X copy(X object) { ... } 

可能,你可以使用静态泛型方法的初步实践相结合,结果变得更友好一点:

public interface Thing extends Cloneable { 
    public static <X extends Thing> X copy(X thing) { 
     Object clone = thing.clone(); 
     if (clone.getClass() != getClass()) 
      throw new RuntimeException("Copy has wrong type!"); 
     return (X)clone; 
    } 
} 

public class ThingA implements Thing { 
    public Object clone() { ... } 
} 

/*code somewhere*/ { 
    ThingA a1 = new ThingA(); 
    ThingA a2 = Thing.copy(a1); 
} 

尽管如此,克隆方法是一个例外,而不是语言的限制规定,但我认为这是目前最好的解决方案。