从方法返回值而不创建对象

时间:2013-04-19 01:33:21

标签: java class methods

好的,我有一个类似于THIS

的大型类结构

它的学校和我的导师喜欢星际争霸,所以我们就去吧。

无论如何,我在 GeneratorBuilding 类中有一个方法,它应该能够实例化一个新的 Marine 对象。但是,我需要知道 Marine 对象需要多少资源。

我在抽象的 Unit 类中有一个名为unitCost()的抽象int方法。然后 Marine 类重写此方法并返回一个类似于50的值。

我正在寻找一种方法让 GeneratorBuilding 类获取 Marine 类中unitCost()方法的返回值,而无需调用任何特定的Marine对象。< / p>

我知道我可能会创建一个海洋对象,然后询问它的成本是多少,然后如果我没有资源,我会删除对象而不是将其推入ArrayList。但这看起来几乎就像一个解决方法。

编辑:重点是能够让我的所有具体类继承并覆盖UnitCost()方法。所以我可以使它静止,但这会破坏继承结构的整个点......

EDIT2:因为有一个示例代码请求(不是很难想象)

public void makeMarine(){

    //uses resources and throws exception etc if there are not enough resources
    Game.useResources(Marine.unitCost());

    //creates a marine
    Game.addMarine();
}

3 个答案:

答案 0 :(得分:2)

您可以通过在每个类中声明一个特别命名的静态字段,并通过 reflection }来实现此目的。

假设您的类看起来像这样:

class ClassNumber1 {
    public static final int cost = 123;
}
class ClassNumber2 {
    public static final int cost = 321;
}

然后您可以获得这样的cost字段:

public static <T> int getCost(Class<T> cl) throws Exception {
    // This is oversimplified: you need to check that the class
    // indeed has a field called "cost" by null-checking the return value
    // of getField(), verifying your cast, catching exceptions, and so on.
    // But this will work in a "closed" system, when you know for sure
    // that an int constant field does exist:
    return (int)cl.getField("cost").get(null);
}

您可以按如下方式调用该方法:

System.out.println(getCost(ClassNumber1.class));
System.out.println(getCost(ClassNumber2.class));

这是demo on ideone

答案 1 :(得分:2)

如果你真的想要一个好的,抽象的OO解决方案来解决这个问题,你应该使用 Abstract Factory Pattern

基本上,这意味着您创建一个“工厂”类,其唯一的工作是创建特定类型的单元。关于工厂类的好处是你可以创建一个接口来表示你的整个工厂集,然后传递工厂的实例 - 这对普通的类构造函数来说并不是真的。

一种常见的模式(我建议在这里)是将 Anonymous Inner Classes 与您的抽象工厂类或接口一起使用,为每个单元类型创建“工厂”的单个实例。 / p>

这里有一些示例代码可以帮助您入门:

/**
 * Abstract class for Starcraft units
 */
public abstract class AUnit {
  // . . .
}

/**
 * Abstract factory for creating Starcraft units
 */
public abstract class AUnitFactory {
  public abstract int unitCost();
  public abstract AUnit createUnit();
}

public class Marine extends AUnit {

  public static final int COST = 50;

  /**
   * Using an anonymous inner class to create an
   * AUnitFactory instance for Marines
   */
  public static final FACTORY = new AUnitFactory() {
    public int unitCost() { return COST; }
    public AUnit createUnit() { return new Marine(); }
  }

  // . . .

}

public class Zergling extends AUnit {

  public static final int COST = 25;

  /**
   * Using an anonymous inner class to create an
   * AUnitFactory instance for Zerglings
   */
  public static final FACTORY = new AUnitFactory() {
    public int unitCost() { return COST; }
    public AUnit createUnit() { return new Zergling(); }
  }

  // . . .

}

/**
 * Starcraft game!
 */
public class Game {

  public addUnit(Player player, AUnitFactory unitFactory) {
    // Get unit's cost
    int cost = unitFactory.unitCost();
    // Now deduct it from the player's resources
    // . . .
    // Create the unit
    AUnit unit = unitFactory.createUnit();
    // Now add the unit to the game for the given player
    // . . .
  }

  // . . .

}

现在您可以执行Game.addUnit(player1, Zergling.FACTORY)Game.addUnit(player2, Marine.FACTORY)

之类的操作

好处是你可以传递 FACTORY 实例,因为它们只是AUnitFactory类型的对象。这意味着您可以执行类似组合框选择单元类型的操作,然后单击一个按钮,创建当前在组合框中选择的单元类型之一。

答案 2 :(得分:0)

这正是类方法的用途。在类方法中,unitCost()是Marine类本身的一个方法(即static public int UnitCost()),因此你可以调用Marine.unitCost(),而不是m = new Marine()然后调用m.UnitCost( )。

酷教练。我希望在服用OO时有一个。