【问题标题】:Java interface function with extra parameter带有额外参数的 Java 接口函数
【发布时间】:2016-05-26 16:29:23
【问题描述】:

我是 Java 和 OOP 的初学者。我有一个界面,例如动物,可以喊叫。

public interface Animal{
    public void shout();
}

我的班级Dog实现了接口,可以对任何人大喊大叫。

public class Dog implements Animal{
    public void shout(){
        System.out.println("Woof woof");
    }
}

我想要一只特定的狗,SmarterDog 类,它可以对特定的人大喊大叫。

所以我的函数是void shout(String somebody),所以我们只有一个额外的参数,但仍然大致相同的代码。它仍然是Animal,所以它应该实现Animal

如何组织我的代码来模拟这个功能? 对于更复杂的功能,我应该怎么做?我应该在实现我的接口的类中创建一个额外的函数吗?

【问题讨论】:

  • "我应该在实现我的接口的类中创建一个额外的函数吗?" 是的。

标签: java design-patterns interface


【解决方案1】:

接口中的方法shout()SmarterDog类中的方法shout(String somebody)同名但方法不同。在 Java 中,方法不仅由其名称标识,而且由其参数类型标识。

它们的实现可能有一些重叠,但这不相关。接口与实现无关。 (Java 8 确实允许您在接口中定义默认方法实现,但这主要是添加到语言中的一项便利功能。)

您可以做的是将通用代码放入某个其他类的辅助方法中,并从两个shout 方法中调用它。您还可以定义一个负责喊叫的类并将它的一个实例添加到您的动物对象中。这基本上是策略模式的实现——听起来很复杂,但如果你的类层次结构变得更复杂,它可能是值得的。主要优点是Animal 的“喊”方面与其他方面是分开的。

我可能还会将带有参数的方法名称更改为 shoutTo(String somebody) 以使其更清晰。

【讨论】:

    【解决方案2】:

    Java 8 引入了default methods,它允许您在接口中指定一个默认实现,实现类不需要定义就不需要定义。

    您的示例对此不太适用,因为尚不清楚 shout(String)shout() 是如何关联的(即似乎不会调用另一个),但稍微不同的 API 会起作用:

    public interface Animal {
      /** Shout, including a message. */
      void shout(String message);
    
      /** Shout without a custom message. */
      default void shout() {
        shout("");
      }
    }
    

    由于接口中定义了shout(),所有实现都免费获得它,他们只需要实现shout(String),它可能看起来像这样:

    public void shout(String message) {
      String call = "Woof woof";
      if (!message.isEmpty()) {
        call += ", " + message;
      }
      System.out.println(call);
    }
    

    默认方法有一些限制(它们必须是公共的,它们无法访问对象的字段等),但对于避免子类中的冗余方法实现非常有用。

    【讨论】:

    • 但这不是说实现接口的所有类都需要实现shout(String)
    • 嗯,是的;这就是接口的重点。就像我说的 API OP 描述的与 default 方法不兼容,但类似的方法(例如我的示例)可能是。
    • 据我理解原来的问题,实现接口的所有类应该有shout(),但只有其中一些应该有shout(String)。因此,我不会称您的实现类似于原始要求。
    • 我建议一种替代方法来构建您的代码,该方法简单、标准和现代,希望它有助于 OP 设计更好的界面。
    • 还是不明白。为什么你建议在接口中声明一个只对该接口的特定实现有意义的方法?这不违反所有设计规则吗? (您关于默认实现的观点可能对 OP 有所帮助,但并未解决他的主要问题。)
    【解决方案3】:

    我想要一只特定的狗,SmarterDog 类,它可以对特定的人大喊。

    创建一个扩展 Dog 的新类。

    如何组织我的代码来模拟这个功能?

    在新创建的类中添加你需要的方法。

    它仍然是一个 Animal,所以它应该实现 Animal。

    SpecificDog 仍然是 Animal。

    public class SpecificDog extends Dog {
        public void shout(String somebody) {
            System.out.println("Woof at " + somebody);
        }
    }
    

    对于更复杂的功能应该怎么做?我应该在实现我的接口的类中创建一个额外的函数吗?

    据我了解,您需要将特定行为添加到扩展 Dog 和/或实现 Animal 的特定类中。因此,只需创建具有必要行为(方法)的类。不要从一开始就使您的模型过于复杂。尽量保持你的抽象尽可能简单。如果您发现可以向上移动(到类/接口)的合同,那就去做吧。

    // somewhere in your code
    SpecificDog dog = new SpecificDog();
    dog.shout();
    dog.shout("stranger");
    

    输出

    Woof woof
    Woof at stranger
    

    【讨论】:

      猜你喜欢
      • 2018-12-06
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 2019-12-19
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多