Java:具有静态方法的类的集合——如果静态接口方法不是';顺便问一下,还有别的吗?

Java:具有静态方法的类的集合——如果静态接口方法不是';顺便问一下,还有别的吗?,java,static,Java,Static,在Java中,是否有一种设计模式或技巧可以处理“我希望在接口中声明静态方法,以便强制我的类实现它们?”我最近读了很多关于接口中的静态类的文章,但没有什么能够满足这个特定问题 例如: 假设我在做一个游戏,我们叫它星际克隆。我有一个保存文件,列出了士兵和野兽最后的已知位置。假设其中一个动物是一个叫做虫族的单位。我的游戏AI想知道它的部队中有多少虫族,因为如果这个数字超过某个阈值,它将在玩家的基地执行“虫族冲刺”攻击。对于本例,该值存储为Zerkling类成员的静态整数 现在,我很想强调这样一个事实,

在Java中,是否有一种设计模式或技巧可以处理“我希望在接口中声明静态方法,以便强制我的类实现它们?”我最近读了很多关于接口中的静态类的文章,但没有什么能够满足这个特定问题

例如:
假设我在做一个游戏,我们叫它星际克隆。我有一个保存文件,列出了士兵和野兽最后的已知位置。假设其中一个动物是一个叫做虫族的单位。我的游戏AI想知道它的部队中有多少虫族,因为如果这个数字超过某个阈值,它将在玩家的基地执行“虫族冲刺”攻击。对于本例,该值存储为Zerkling类成员的静态整数

现在,我很想强调这样一个事实,即每个单元的类都有一个方法countsHowMany,它接受这个保存文件并查看该特定单元中有多少个存在——至少它可以这样做,但每个类都会按照自己的意愿实现它。因为成员变量是静态的,所以设置它的方法也是静态的似乎是明智的。我可能没有可以调用非静态countsHowMany方法的Zerkling实例,因为计数可能为0。我们可以说变量可能是从0开始初始化的,但是想想初始值不可用的情况;e、 在我的实际项目中,我正在检索游戏精灵图像;它们以null开头

这似乎是一个非常有效的设计,只需在一个点上列出我所有的士兵和野兽类,通过一个接口将它们分组到一个集合中,我们可以自己称之为ICount。所以我们可以做一些类似的事情:

for ( Class <? extends ICountMyself> currentClass : listOfUnitClasses )
{
    currentClass.countHowMany( savedGameFile );
} 

for(Class我认为你不希望在
Zerkling
类中使用它。Class
Zerkling
类的对象表示一个单位,但听起来你可能希望一个对象表示某一类型单位的整个组(组大小可以是0),每种单位类型有一个这样的对象。
countHowMany()
方法将是为您的“组”类定义的实例方法。您可以使用
countHowMany()
方法定义接口或抽象类,其他每个类
groupofzerklins
等将扩展该方法


这不是唯一的解决方案。如果您只想对每种类型的单元进行计数,则可以使用
Map
来完成这项工作。关键是
Zerkling.class
或其他什么。但是“组对象”是一种可能的解决方案;它是否是最好的解决方案取决于应用程序其余部分的需求。

您应该利用。您实例化了一些
Zerkling
s,它们派生自
Beastie
,反过来又派生自
MilitaryUnit
。使用
java.util.Set
要保存这些单元的列表:毕竟,每个单元都必须是唯一的,因此只能在
集中出现一次。
集将强制执行此操作

因此,您可能有:

Set<Zerkling> zerklings = new HashSet<Zerkling>();
//... elsewhere in code
zerklings.size();//Number of zerklings you have.

使用静态方法运行的问题是,你不能清楚谁或什么时候调用方访问该方法。这使得多线程最难管理(如果你正在做一个实际的游戏,你可能有多个线程,如果只运行到异步UI)。考虑以下内容:

* Call to static method to set value to x
* Mid-call thread is suspended and another thread picks up
* That thread sets value to y
* First call completes, no one knows if they have the right value.

请记住,拥有该类的任何人都可以修改静态类字段。即使该类没有被积极用于表示“活”虫族,例如,如果您使用它来表示在虫族蜂巢中生长的虫族,或在您的“帮助”菜单中,或任何其他可能调用该类的地方。

要在接口中使用静态方法使其在其他类中实现,Java的方法是使用新的通用接口实现该方法

对于您的用例,让我们将其称为一个
Bunch
,并假设您的所有士兵和野兽类都实现了
Countable

interface Bunch<T extends Countable> {
    void add(T elt);
    void remove(T elt);
    int count();
}

这种模式甚至允许您在同一个应用程序中拥有不同的分支。

我觉得您遇到了过度使用/误用静态变量时所遇到的问题之一

您遇到的问题是无法在Java中为
静态方法执行多态性:

  • 不能说给定类的所有子类都必须实现给定的静态方法

  • 调用静态方法没有多态方式。在源代码中对静态方法的调用在编译时绑定到特定类提供的特定静态方法的签名

因此,如果
countHowMany
是一个由许多类实现的静态方法,那么您会发现必须执行以下操作:

  int total = Class1.countHowMany() + Class2.countHowMany() + ...
  for ( Class <? extends ICountMyself> currentClass : listOfUnitClasses )
…诸如此类:

  int total = Class1.countHowMany() + Class2.countHowMany() + ...
  for ( Class <? extends ICountMyself> currentClass : listOfUnitClasses )

对于(类“我的游戏AI想知道它的部队中有多少虫族”,那么“游戏”类负责计数,而不是“虫族”类如果你有一堆类都定义了相同的静态方法,你不能多态地调用它,这意味着你必须调用
虫族。countHowMany()
OtherUnit.countHowMany()
YetSomethingElse.countHowMany()
,在您的代码中明确说明。或者您对如何执行此操作有其他想法吗?@RC您说得很对,因为我需要更多地了解我需要这些信息的原因,而不仅仅是我使用这些信息的方式。我将试着在编辑中详细说明。@ajb您给了我一个好主意。重新审视这个问题,我意识到我忽略了一个重要的问题首先,类是如何进入列表的?我假设我只调用了一个函数,那么说Zerkling.counthowny(),Metalisk.countHo同样容易
  for ( Class <? extends ICountMyself> currentClass : listOfUnitClasses )