5

我有一个具有抽象 getType() 方法的基类。我希望子类能够实现此方法并提供要使用的实际类。

在代码中,类似于以下内容:

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

这里的问题是我在标记的行中得到“MyTile 无法解决”。所以我试图返回这个:

返回新的 MyTile().getClass()

但现在 Eclipse 告诉我:

类型不匹配:无法从 Class <capture#1-of 转换?将 B.MyTile 扩展为A.Tile><>

我什至不确定 Eclipse 中是否存在错误(捕获#1?)。

接下来,我将放弃接口并尝试使用抽象基 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"
    }
}

所以我基本上似乎有三个问题:

1)是否有可能让它与 A.Tile 作为接口一起使用?

2)使用基类时,Class<? extends X>真的是正确的方法吗?

3) 如何从方法内部返回嵌套的 B.MyTile 类引用?不得不做的事情new MyTile().getClass()是不对的,不是吗?

4

2 回答 2

6

泛型和协变类型覆盖不能很好地协同工作。您必须将 getTileClass() 显式声明为返回一个可以是A.Tile子类的类。

您还可以使用 MyTile.class 访问 MyTile 的类对象,而无需实例化它。

试试这个:

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

更好的是使 A 通用。您仍然必须在类类型定义中使用扩展,但您可以更具体一点:

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;
    }
}
于 2009-04-08T18:10:18.963 回答
-1
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();
    }
}

不需要泛型,你只想说你返回一个 Tile 或 Tile 子类。

顺便说一句,类中的公共静态接口是“代码气味”;要么使其受到保护,因此只有 A 的子类才能实现 Tile,要么将其放在自己的顶级接口中。加入一个但允许任何人实施它会发出一个混合的信息。

于 2009-04-08T18:13:59.750 回答