Creating a common interface limited to its own class

I would like to create a common interface for these two classes, but I'm not sure how to specify generics correctly.

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

I have tried this.

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

But I can still do things that should not be allowed.

 public class ThingB implements Thing<ThingA> { public ThingA createCopy(ThingA original); } 
+7
java generics interface
source share
4 answers

There are no this keyword generators (and not for method parameters and return value declarations), and therefore you cannot do exactly what you want.

In other words, the interface will ensure that all methods in the class use consistent types, but do not refer to the class type itself.

+6
source share

It's impossible. And that's not what Generics is for. Generics are designed for type safety, i.e. Avoid casting. If someone makes a ThingB class that somehow implements Thing<ThingA> , then fine. It is absolutely safe in type. What do you care? How does this interfere with what you are doing?

+1
source share

You are looking for

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

? If not, can you explain in more detail what it means to you to “create a common interface for two classes”?

0
source share

If you can use the extension instead of the implementation, you can do it like this:

 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(); } 

And then use it like:

 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); } 

One of the problems is that Copyable not an interface. However, this can be used without much effort, as shown in the example, but the used class check is not supported at the language level. In other words, the abstract createCopy method createCopy not limited to the class that it copies, and everything depends on the programmer who extends the Copyable class or the class that extends it.

The .copy() is that if you call .copy() on an object, it should return an object that is the same as it is. Instead of throwing an exception, you can return null if you want. Then you got good or nothing.

But honestly, I really don't understand why your local createCopy method has a parameter. It may be a static method ... altrough I can’t even imagine what would go into this code block:

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

Is it possible to combine pratika with a static universal method and the result will become a little friendlier:

 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); } 

However, the cloning method is governed by exception, not language restriction, but I think this is a far better solution.

0
source share

All Articles