好的,我有一个类似于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();
}
答案 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));
答案 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时有一个。