草庐IT

java - 有没有办法确保实现接口(interface)的类实现静态方法?

coder 2023-05-18 原文

首先,我阅读了埃里克森对 "Why can’t I define a static method in a Java interface?" 的有用回复.这个问题不是关于“为什么”,而是关于“那么如何?”。


编辑:我原来的例子不合适,但我会把它留在下面。

虽然我现在确信,在大多数情况下,我想做的事是矫枉过正,但有一种情况可能需要它:

我将再次使用 ParametricFunction 示例。现在让我们使用一个复杂的函数,例如 Bessel functions ,查找表是合适的。这必须被初始化,所以这两个选项是将参数直接传递给构造函数或提供 init(double[] parameters)。后者的缺点是 getValue(double x) 必须在每次调用时检查初始化(或 ArrayIndexOutOfBoundsException 必须被视为初始化检查),因此对于时间关键的应用程序我更喜欢构造方法:

interface ParametricFunction {
  public double getValue(double x);
}

class BesselFunction implements ParametricFunction {
  public BesselFunction(double[] parameters) { ... }
  public double getValue(double x) { ... }
}

这涉及到另一个问题,接口(interface)中的构造函数是不可能的。那里有什么好的解决方案?我当然可以使用 init(double[] parameters) 方法,但我提到了我不这样做的原因。 (编辑:好的,这里有一个实现接口(interface)的抽象类)

现在让我们假设 ParametricFunction 只允许某些参数,例如正整数。如何检查传递给构造函数的参数的有效性?抛出 IllegalArgument 异常是可能的,但 checkParametersValidity(double[] parameters) 似乎更方便。但是需要在构造之前检查参数,所以它必须是静态方法。这就是我真的很想知道一种方法来确保实现 ParametricFunction 接口(interface)的每个类都定义了这个静态方法。

我知道这个例子是相当人为的,而不是简单地通过接口(interface)使用 init 方法的原因是有争议的,我仍然想知道答案。如果您不喜欢它,请将其视为学术问题。

(原始示例)

所以基本上我想要一个接口(interface)来提供常用方法,例如getSimilarObject 方法。对于(编造的)例子

public interface ParametricFunction {
  /** @return f(x) using the parameters */
  static abstract public double getValue(double x, double[] parameters);

  /** @return The function's name */
  static abstract public String getName();

  /** @return Whether the parameters are valid  [added on edit] */
  static abstract public boolean checkParameters(double[] parameters);
}

然后

public class Parabola implements ParametricFunction {
  /** @return f(x) = parameters[0] * x² + parameters[1] * x + parameters[2] */
  static public double getValue(double x, double[] parameters) {
    return ( parameters[2] + x*(parameters[1] + x*parameters[0]));
  }
  static public String getName() { return "Parabola"; }
  // edit:
  static public boolean checkParameters(double[] parameters) {
    return (parameters.length==3);
  }
}

既然当前的 Java 标准不允许这样做,那么最接近这个的是什么?

这背后的想法是将几个 ParametricFunction 放在一个包中,并使用反射将它们全部列出,允许用户选择例如绘制哪一个。显然,我们可以提供一个加载器类,其中包含一组可用的 ParametricFunction,但每次实现一个新的时,都必须记住在其中添加它。

编辑:调用它的一个例子是

public double evaluate(String fnName, double x, double parameters) throws (a lot) {
  Class<ParametricFunction> c = (Class<ParametricFunction>) ClassLoader.getSystemClassLoader().loadClass(fnName);
  Method m = c.getMethod("getValue", x, parameters);
  return ((double) m.invoke(null));
}

并调用 evaluate("Parabola", 1, new double[]{1,2,0});.

最佳答案

不能要求类通过接口(interface)实现特定的静态方法。这在 Java 术语中毫无意义。接口(interface)强制在实现接口(interface)的类中存在特定的非静态方法;他们就是这样做的。

最简单的方法肯定是使用某种工厂类来生成其他工厂类的实例。是的,这确实意味着您必须记住在添加新实例时使该工厂保持最新状态,但是由于您在进行新实现时要做的第一件事就是对其进行测试(您确实对其进行了测试,是吗?)很快就会解决这个问题!

关于java - 有没有办法确保实现接口(interface)的类实现静态方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2689312/

有关java - 有没有办法确保实现接口(interface)的类实现静态方法?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  6. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  9. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐