2 回答

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);
}
}
}

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();
}
}
添加回答
舉報