在Java中返回嵌套的类类型

时间:2009-04-08 18:04:27

标签: java class oop nested-class

我有一个具有抽象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告诉我:

  

类型不匹配:无法转换   类<捕获#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()不对,可以吗?

2 个答案:

答案 0 :(得分: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;
    }
}

更好的做法是通用。您仍然必须在类类型定义中使用 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;
    }
}

答案 1 :(得分:-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,或者将它放在自己的顶级接口中。放入但允许任何人实现它会发送混合消息。