Java'da arayüzlerde ne zaman özel bulut sunucusu yöntemleri kullanmalıyız?


9

Java 9'dan itibaren, bir arabirimdeki yöntemler özel olabilir. Özel bir yöntem statik veya örnek bir yöntem olabilir. Özel yöntemler sadece arayüzün kendi yöntemlerinde kullanılabileceğinden, kullanımları arayüzün diğer yöntemleri için yardımcı yöntemler ile sınırlıdır.

Cay S. Horstmann, Temel Java Cilt I - Temel Bilgiler

Ortak işlevsellikleri özel yöntemlere koyabilir ve herkese açık hale getiremeyeceğimizi anlıyorum. Ancak burada iki tür özel yöntemimiz olabilir:

  1. private
  2. private static

private staticYöntemleri kullanmak anlaşılabilir, ancak privateyöntemleri ne zaman kullanmalıyız ? Buradaki örneklerle ilgilenmiyoruz, çünkü bu bir arabirim, neden privateyöntem oluşturmaya izin veriliyor? Sadece private staticyöntemlere ihtiyacımız yok mu?


Bir arabirim, diğer yönetim ortamı yöntemlerinin çağırdığı ancak kamu tüketimine yönelik olmayan yöntemler içerebilir.
Dave Newton

2
Arabirimi privateuygulayan sınıfta arabirimin örnek yöntemini çağırmayı deneyin .
Abra

1
Böyle bir özel yöntem, arabirimden diğer yöntemleri çağırabilir, bu nedenle private staticyöntemlerle eşdeğer değildir veya değiştirilemez .
Mark Rotteveel

belki de varsayılan yöntemler
Maurice Perry

Yanıtlar:


2

Tamam, OP'nin sorularını yanıtlamaya yönelik başka bir girişim. Özel bir yöntemden arabirimde statik olmayan başka bir yöntem çağırmanız gerektiğinde, özel yöntem statik olamaz. Örneğin, aşağıdaki özel yöntem statik olsaydı bir derleme hatası olurdu:

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

Bu neden önemli? Ayrıca her yöntemi "genel varsayılan" olarak da uygulayabilirsiniz. Soru, x veya y uygulamasını neden / hangi amaçla seçeceğinizle ilgilidir - nasıl değil.
Florian Salihovic

2
@FlorianSalihovic, bu özel yöntemden başka bir yöntem çağırmanız gerektiğinde statik olmayan statik üzerinden seçersiniz. Nedeni bu değil mi?
jingx

Yanlış soruyu soruyorsun. Metotların görünürlüğü, nesnelerin birbirleriyle nasıl etkileştiklerine dair olasılıkları daraltmak veya genişletmek için seçilir. İletişim kuran geliştiriciler, kodlarının nasıl kullanılması / kullanılması / kullanılması gerektiği konusunda niyet aldığından önemlidir. Her şeyi statik yöntemlerle uygulayabilir veya hiç statik yöntem kullanamazsınız. Soru, diğer nesnelerin / sınıfların işlevselliğe erişmesinin sonuçlarını hiç düşünmemiz gerektiğinden düşünmemiz gerektiğinden önemlidir.
Florian Salihovic

2
@FlorianSalihovic Ama insanların yorumlarından öğrendiğim gibi, OP görünürlük veya statik olmayan veya statik olmayan ne zaman kullanılacağını sormuyordu, bunun yerine özel statik görünüşte yeterli olduğunda arayüzlerde statik olmayan özel yöntemlere neden izin verildiğini soruyorlardı. Cevabım, yalnızca statik olmayan bir yöntemin işe yarayacağı bir kullanım durumu sağladı.
jingx

3

Arabirimler bir nesnenin davranışını tanımlamak için kullanılır. Bu araçlar her arabirimin yöntemlerden maruz kalmaktadır. Varsayılan yöntemleri kullanırken, sınıf sınırları boyunca kodun yeniden kullanılmasını sağlayarak tanımlı yöntemlerin standart uygulamalarını sağlayabiliriz.

Bazı durumlarda, işlevsellik gerekir (belki de yalnızca farklı varsayılan yöntemlerde kodun yeniden kullanılması için ), ancak sınıfın / nesnenin ad alanlarını kirleteceği için açıklanmamalıdır. Bu, özel varsayılan yöntemlerin işe yaradığı yerdir . Özel varsayılan yöntemlere örnek olarak fabrikalar, doğrulamalar veya varsayılan durum işleme verilebilir.

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);
    }
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.