I have a base class that has an abstract getType() method. I want subclasses to be able to implement this method and provide the actual class to use.
我有一个具有抽象getType()方法的基类。我希望子类能够实现此方法并提供要使用的实际类。
In code, something like the following:
在代码中,类似于以下内容:
public abstract class A {
public static interface Tile;
protected abstract Class<Tile> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
@Override
protected abstract Class<A.Tile> getTileClass() {
MyTile t = new MyTile(); // WORKS
return MyTile; // ERROR HERE
}
}
The problem here is that I get "MyTile cannot be resolved" in the line marked. So I'm trying to return this instead:
这里的问题是我在标记的行中得到“MyTile无法解析”。所以我试图回复这个:
return new MyTile().getClass()
返回新的MyTile()。getClass()
but now Eclipse tells me:
但现在Eclipse告诉我:
Type mismatch: cannot convert from Class
<
capture#1-of ? extends B.MyTile>
to Class<
A.Tile>
类型不匹配:无法转换为Class
扩展到Class #1-of?将b.mytile>
which I'm not even sure if there's maybe a bug in Eclipse here top (capture#1?).
我甚至不确定Eclipse中是否有可能存在错误(捕获#1?)。
Next, I'm giving up on interfaces and trying to use an abstract base Tile class. With some help from Eclipse, I end up with the following code that seems to compile:
接下来,我放弃接口并尝试使用抽象基础Tile类。在Eclipse的帮助下,我最终得到了以下似乎编译的代码:
public abstract class A {
public static abstract class Tile;
protected abstract Class<? extends Tile> getTileClass();
}
public class B extends A {
public static class MyTile exends A.Tile { }
@Override
protected abstract Class<? extends A.Tile> getTileClass() {
return new MyTile().getClass(); // WORKS
return MyTile; // "Cannot be resolved"
}
}
So I basically seem to have three questions:
所以我基本上似乎有三个问题:
1) Is it possible to get this to work with A.Tile being an interface?
1)是否可以使用A.Tile作为界面?
2) When using a base class, is Class<? extends X>
really the correct way to go?
2)使用基类时,Class 真的是正确的方法吗?
3) And how can I return my nested B.MyTile class reference from inside the method? Having to do new MyTile().getClass()
can't be right, can it?
3)如何从方法内部返回嵌套的B.MyTile类引用?不得不做新的MyTile()。getClass()不能正确,可以吗?
2 个解决方案
#1
Generics and covariant type overriding do not work very well together. You have to explicitly declare getTileClass() as returning a class that can be a subclass of A.Tile.
泛型和协变类型覆盖不能很好地协同工作。您必须显式声明getTileClass()为返回可以作为A.Tile的子类的类。
You also can access the class object of MyTile without instanciating it, with MyTile.class.
您还可以使用MyTile.class访问MyTile的类对象,而无需对其进行实例化。
Try this instead:
试试这个:
public abstract class A {
public static interface Tile;
protected abstract Class<? extends Tile> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
@Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
Even better would be to make A generic. You still have to use extends in the class type definition, but you can be a bit more specific:
更好的是制作A通用。您仍然必须在类类型定义中使用extends,但您可以更具体一些:
public abstract class A<T extends A.Tile> {
public static interface Tile;
protected abstract Class<? extends T> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
@Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
#2
public abstract class A {
public static interface Tile {};
// I return something that is-a Tile
protected abstract Tile getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
@Override
protected abstract Tile getTileClass() {
return new MyTile();
}
}
No need for generics, you just want to say that you return a Tile or Tile subclass.
不需要泛型,你只想说你返回一个Tile或Tile子类。
Incidentally, a public static interface in a class is a "code smell"; either make it protected, so only subclasses of A can implement Tile, or put it in its own top-level interface. Putting in a but allowing anyone to implement it sends a mixed message.
顺便提一下,类中的公共静态接口是“代码气味”;要么保护它,所以只有A的子类可以实现Tile,或者将它放在自己的*接口中。放入但允许任何人实现它会发送混合消息。
#1
Generics and covariant type overriding do not work very well together. You have to explicitly declare getTileClass() as returning a class that can be a subclass of A.Tile.
泛型和协变类型覆盖不能很好地协同工作。您必须显式声明getTileClass()为返回可以作为A.Tile的子类的类。
You also can access the class object of MyTile without instanciating it, with MyTile.class.
您还可以使用MyTile.class访问MyTile的类对象,而无需对其进行实例化。
Try this instead:
试试这个:
public abstract class A {
public static interface Tile;
protected abstract Class<? extends Tile> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
@Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
Even better would be to make A generic. You still have to use extends in the class type definition, but you can be a bit more specific:
更好的是制作A通用。您仍然必须在类类型定义中使用extends,但您可以更具体一些:
public abstract class A<T extends A.Tile> {
public static interface Tile;
protected abstract Class<? extends T> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
@Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
#2
public abstract class A {
public static interface Tile {};
// I return something that is-a Tile
protected abstract Tile getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
@Override
protected abstract Tile getTileClass() {
return new MyTile();
}
}
No need for generics, you just want to say that you return a Tile or Tile subclass.
不需要泛型,你只想说你返回一个Tile或Tile子类。
Incidentally, a public static interface in a class is a "code smell"; either make it protected, so only subclasses of A can implement Tile, or put it in its own top-level interface. Putting in a but allowing anyone to implement it sends a mixed message.
顺便提一下,类中的公共静态接口是“代码气味”;要么保护它,所以只有A的子类可以实现Tile,或者将它放在自己的*接口中。放入但允许任何人实现它会发送混合消息。