【问题标题】:How to pass type of object to class?如何将对象类型传递给类?
【发布时间】:2012-07-20 20:14:18
【问题描述】:

我目前正在使用 slick2D 在 java 中制作游戏。游戏是基于瓷砖的,我正在尝试生成随机地图。我正在生成一个房间和一个连接到那个房间的走廊,并继续这样做,直到地图全部填满。我有诸如

之类的方法
generateRoom(int x, int y, int width, int height)

我的问题是如何传递我想在房间中使用的 Tile 类型。我认为它可能看起来像这样

generateRoom(StoneTile, int x, int y, int width, int height)

显然这不起作用。我不想发送已经创建的实际图块,因为每个图块中都有一个特定的位置,并且在调用该方法时我不知道图块的位置。我将如何发送要在方法中使用的类型?

【问题讨论】:

    标签: java class object types slick2d


    【解决方案1】:

    您可能只想发送Class,因此请使用以下内容:

    generateRoom(Class tileClass, int x, int y, int width, int height)
    

    然后您可以使用对象上的getClass() 方法调用它。

    【讨论】:

    • 如果你使用 Java 5,你可以使用 Class 以进一步将参数限制为特定类型(或子类型)
    • 或者,比getClass()StoneTile.class更适合这种情况。
    【解决方案2】:

    这完全取决于您想对该类型信息做什么。听起来您想在编译时不知道该类型是什么的情况下创建给定类型的新对象。这意味着 Java 泛型,可用于向方法添加类型信息,如下所示:

    <T> generateRoom(int x, int y, int width, int height)
    

    不会工作,因为你不能写new T()。 (Java 编译器会在运行前删除通用信息)。

    因此,您可以尝试将反射与泛型结合使用,在这种情况下,您可以将 Class 对象传递给您的方法,并使用 Java 的反射实用程序为您提供的类找到构造函数。

    <T> generateRoom(Class<T> tileClass, int x, int y, int width, int height) {
        Constructor<T> constructor = tileClass.getDeclaredConstructor(Arg1Type.class, Arg2Type.class);
        T tile = constructor.newInstance(arg1, arg2);
    }
    

    请参阅herehere,了解有关在构造函数中使用反射的更多信息。

    或者,如果您不想冒反射的脆弱性,您可以使用工厂模式并将您的方法传递给工厂以构造适当的 Tile:

    generateRoom(TileFactory tileFactory, int x, int y, int width, int height) {
        Tile myTile = tileFactory.getInstance();
    }
    

    为了做到这一点,你需要有一个接口Tile,你的所有瓦片类型都实现了,还有一个接口TileFactory,每个具体瓦片工厂(即StoneTileFactory)都实现了。那么当你调用该方法时,如果你想让它创建 StoneTiles,你可以给它一个 StoneTileFactory(符合 TileFactory 参数类型)。

    当然,如果您不想使用接口,即使这也可以使用泛型参数化:

    <T> generateRoom(TileFactory<T> tileFactory, int x, int y, int width, int height) {
        T tile = tileFactory.getInstance()
    }
    

    在这种情况下,您需要使TileFactory 的每个实例都实现TileFactory&lt;TileType&gt;,例如TileFactory&lt;StoneTile&gt;,并适当地参数化工厂的getInstance 方法(public T getInstance())。

    【讨论】:

      【解决方案3】:

      我认为满足您需求的一种简单方法是创建一个表示图块类型的枚举:

      public enum TileType {
          STONE,
          WATER,
          FIRE,
          GRASS
      }
      

      然后您可以像这样通过您的方法传递类型:

      TileType type = TileType.STONE;
      generateRoom(type, x, y, width, height);
      (...)
      

      如果您以后需要为每个图块类型枚举添加参数或行为,请转到 a long way 以适应这一点。

      【讨论】:

        猜你喜欢
        • 2020-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        相关资源
        最近更新 更多