为了账号安全,请及时绑定邮箱和手机立即绑定

在Java中,什么时候应该在接口中使用私有实例方法?

在Java中,什么时候应该在接口中使用私有实例方法?

慕婉清6462132 2023-09-27 16:16:04
从 Java 9 开始,接口中的方法可以是私有的。私有方法可以是静态方法或实例方法。由于私有方法只能在接口本身的方法中使用,因此它们的使用仅限于作为接口其他方法的辅助方法。Cay S. Horstmann,核心 Java 第 I 卷 - 基础知识我知道我们可以将通用功能放在私有方法中,而不是使其可供公众访问。但我们在这里可以有两种私有方法:privateprivate static使用private static方法是可以理解的,但是什么时候应该使用private方法呢?我们在这里不处理实例,因为这是一个接口,那么为什么private允许创建方法呢?我们不需要的只是private static方法吗?
查看完整描述

2 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

接口用于定义对象的行为。这意味着所有接口的方法都被公开。当使用默认方法时,我们可以提供已定义方法的标准实现,从而提供跨类边界的代码重用。


在某些情况下,功能是必需的(也许只是为了在不同的默认方法中重用代码),但不应公开,因为它会污染类/对象的名称空间。这就是私有默认方法派上用场的地方。私有默认方法的示例可以是工厂、验证或默认状态处理。


package com.company;


import java.util.List;

import java.util.function.Predicate;

import java.util.stream.Collectors;


public class Main {


  public static void main(final String[] args) {

    var messages =

        List.of(

            MessageQueue.newSubject("Message 1"),

            MessageQueue.newTopic("Message 2"),

            MessageQueue.newTopic("Message 3"));

    final MessageQueueAdapter1 queue1 = () -> messages;

    inspectQueue(queue1);

    final MessageQueueAdapter2 queue2 = () -> messages;

    inspectQueue(queue2);

  }


  private static void inspectQueue(final MessageQueue queue) {

    final List<Message> messagesWithSubject = queue.getMessagesWithSubject();

    assert messagesWithSubject.size() == 1 : "expected one message with 'Subject'";

    final List<Message> messagesWithTopic = queue.getMessagesWithTopic();

    assert messagesWithTopic.size() == 2 : "expected two message with 'Topic'";

    assert !queue.getMessages().isEmpty() && 3 == queue.getMessages().size()

        : "expected three messages in total";

  }


  @FunctionalInterface

  interface Message {

    private static boolean isPrefixedBy(final String message, final String prefix) {

      return message != null && !message.isEmpty() && message.startsWith(prefix);

    }


    default boolean hasSubject() {

      return isPrefixedBy(this.getMessage(), MessageQueue.PREFIX_SUBJECT);

    }


    default boolean hasTopic() {

      return isPrefixedBy(this.getMessage(), MessageQueue.PREFIX_TOPIC);

    }


    String getMessage();

  }


  interface MessageQueue {

    String PREFIX_SUBJECT = "Subject: ";


    String PREFIX_TOPIC = "Topic: ";


    private static Message newMessage(final String message) {

      return () -> message;

    }


    static Message newSubject(final String message) {

      return newMessage(PREFIX_SUBJECT + message);

    }


    static Message newTopic(final String message) {

      return newMessage(PREFIX_TOPIC + message);

    }


    List<Message> getMessages();


    List<Message> getMessagesWithSubject();


    List<Message> getMessagesWithTopic();

  }


  @FunctionalInterface

  interface MessageQueueAdapter1 extends MessageQueue {

    private static List<Message> filterBy(

        final List<Message> messages, final Predicate<Message> predicate) {

      return messages.stream().filter(predicate).collect(Collectors.toList());

    }


    /** {@inheritDoc} */

    @Override

    default List<Message> getMessagesWithSubject() {

      return filterBy(this.getMessages(), Message::hasSubject);

    }


    /** {@inheritDoc} */

    @Override

    default List<Message> getMessagesWithTopic() {

      return filterBy(this.getMessages(), Message::hasTopic);

    }

  }


  @FunctionalInterface

  interface MessageQueueAdapter2 extends MessageQueue {

    private List<Message> filterBy(final Predicate<Message> predicate) {

      return this.getMessages().stream().filter(predicate).collect(Collectors.toList());

    }


    /** {@inheritDoc} */

    @Override

    default List<Message> getMessagesWithSubject() {

      return filterBy(Message::hasSubject);

    }


    /** {@inheritDoc} */

    @Override

    default List<Message> getMessagesWithTopic() {

      return filterBy(Message::hasTopic);

    }

  }

}



查看完整回答
反对 回复 2023-09-27
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

好的,再次尝试实际回答OP的问题。当需要从私有方法调用接口上的另一个非静态方法时,私有方法不能是静态的。例如,如果下面的私有方法是静态的,就会出现编译错误:


public interface InterfaceWithMethods {

    public default void doSomething() {

        doSomethingCommon();

    }


    public default void doSomethingElse() {

        doSomethingCommon();

    }


    public void actuallyDoSomething();


    private void doSomethingCommon() {

        System.out.println("Do something first.");

        actuallyDoSomething();

    }

}


查看完整回答
反对 回复 2023-09-27
  • 2 回答
  • 0 关注
  • 51 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信