【问题标题】:How do I specify that an implementing class must contain a particular field?如何指定实现类必须包含特定字段?
【发布时间】:2009-12-28 20:20:46
【问题描述】:

我想写一个抽象类(或接口)

  • 强制所有实现类提供特定类型和名称的字段(理想情况下是静态的)(如果缺少,可能会引发编译时错误?),或者
  • 在实现类时自动提供此类字段。

一个例子是:

public abstract class A {
    abstract int counter;
}

public class B extends A {
    public int getCounter() {
        return counter;
    }
}

在这种情况下,B 的 getCounter() 方法将返回(静态或实例)counter 特定于 B 类,而不是继承自的值 A。有没有办法在 Java 中做到这一点?

【问题讨论】:

  • 为什么它需要是静态的?如果一个接口有... public int getCounter();实现类是否静态执行此操作是否重要(也许他们会跟踪数据库中的计数器)。我不明白你为什么需要限制这一点。

标签: java inheritance abstract-class


【解决方案1】:

没有真正的好方法可以做到这一点,我也不认为应该有。您可以使用抽象方法完成同样的事情,并在基类中编写算法,以便它们利用委托方法。

如果您提供更多关于您认为需要这样做的原因的详细信息,我们可以帮助您制定更正确的解决方案。

例如:

public abstract class A {

    protected abstract int getCounter();

    public void doStuff() {
        int counter = getCounter();
        for (int i=0; i < counter; i++) {
            // do stuff
        }
    }

}

【讨论】:

  • 每个实现 A 的类都需要一个名为 counter 的(静态,理想情况下)变量的自己的副本,以及该计数器的 getter。为了尽量减少重复代码,我希望有办法在 A 中编写一个实际返回 B 计数器的 getter 方法。这是因为将有一个“模板”抽象类(或接口)A,但有许多类似的实现类,例如 B。
  • 变量似乎不需要是静态的。我的例子应该做你想做的。
【解决方案2】:

以类为键,计数器为值,创建一个 HashMap。

【讨论】:

  • 这听起来很可怕,对我来说相当不雅。我正在尝试编写更少的代码,而不是更多。
  • 但这听起来很适合我。 “更少的代码”并不总是合适的。 (顺便说一句,Thorbjorn - 抱歉,今天没有赞成票)
  • this.getClass() 可以帮助您解决问题。
  • 如果你的“更少的代码”最终导致实际功能被隐藏起来,导致那些维护你的代码的人追捕你,要么杀了你,要么让你自己修复它。也要非常小心。
  • bozho,没问题。但是,如果您的回答受到我的启发,我将不胜感激。
【解决方案3】:

接口的主要目的不是告诉它的实现者该做什么。它是告诉其他类它的实现者可以做什么。此外,它不应指定任何实现细节。也就是说,它不应该也不能强加任何变量声明。

如果你想要一个每个子类的计数器,那么在超类中声明一个Map,键=子类的Class,值=计数器值(如建议 Thorbjørn Ravn Andersen 的回答)

【讨论】:

  • 这就是为什么我主要考虑用抽象类来做这件事。
  • 抽象类也指定“一个接口”。虽然不严格通过 interface 关键字。
【解决方案4】:

尝试此处列出的众多工具之一:

http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#Java

我假设这是在一个有多个开发人员的开发环境中。

【讨论】:

  • 这有什么关系..?
  • 是的,它是相关的。这是一种执行他想要的东西的方式
  • 我不是我店里唯一的人,但我是唯一一个(在可预见的将来)编写实现 A 的类的人。我想强迫自己编写一致的实现。
【解决方案5】:

正如其他人所指出的,如果没有大量的额外工作,这在语言中是不可能直接实现的。

我的建议是你遵循 Pace 的建议:不要指定计数器,而是将其指定为接口中的方法。

我建议的唯一区别是您将其重命名为更准确地反映您的意图的名称。比如:


    protected abstract getNumberOfInstancesOfThisClass();

您甚至可以编写一个自动化单元测试生成器来检查它是否已正确实现,即使您可以在抽象类中创建静态成员也必须这样做。 p>

【讨论】:

    【解决方案6】:
    public abstract class A {
       private static Map<Class,Integer> map = new HashMap<Class,Integer>();
       protected A() { map.put(this.getClass(), 0); }
    
       public int getCounter() { return map.get(this.getClass()); }
       public void setCounter(int n) { map.put(this.getClass(), n); }
    }
    
    public class B extends A {
       ...    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 2020-04-21
      • 2021-04-25
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多