Как вы используете частные методы вашего интерфейса? - PullRequest
0 голосов
/ 09 ноября 2018

У меня проблемы с использованием закрытого метода, который я реализовал в своем интерфейсе.

Я реализовал метод print(string, list) в своем интерфейсе RequestData, чтобы скрыть реализацию, поскольку я не хочу, чтобы он вызывался, кроме как другими методами печати класса - но я включил его в интерфейс, потому что он собирается быть одинаковым с каждым реализующим классом.

Проблема в том, что когда я пытаюсь использовать метод print из моего FundingRequests, который реализует интерфейс RequestData, он показывает ошибку - доступ к методу print в интерфейсе RequestData является частным, так что это не может быть найдено.

Хорошо ... как вы должны использовать закрытые методы интерфейса, если они недоступны из реализующих классов?

Это ошибка, или я неправильно понимаю интерфейсы?

Интерфейс:

package com.landbay.datamodel.data;

import java.util.List;

public interface RequestData<E> {

    void add(E newRequest);

    List<E> getRequests();

    List<E> getFulfilledRequests();

    List<E> getUnfulfilledRequests();

    void printRequests();

    void printFulfilledRequests();

    void printUnfulfilledRequests();

    private void print(String listTitle, List<E> listToPrint) {
        StringBuilder string = new StringBuilder();
        string.append(listTitle);

        for (E request : listToPrint) {
            string.append("\n").append(request);
        }

        System.out.println(string);
    }

}

Класс и методы оскорбления:

public class FundingRequests implements RequestData<FundingRequest> {
        private TreeSet<FundingRequest> requests;

        FundingRequests() {
            this.requests = new TreeSet<>();
        }

        ...

        @Override
        public void printRequests() {
            print("",new ArrayList<>(requests));
        }

}

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Частные методы были предоставлены как функция для интерфейсов Java, чтобы помочь писать методы по умолчанию в интерфейсах без повторного использования кода. Они не предназначены для использования при наследовании реализации.

Если вы хотите наследовать и использовать реализованные методы, например, те, которые вы пытались здесь:

@Override
public void printRequests() {
    print("",new ArrayList<>(requests));
}

вы хотите либо реализовать метод в суперклассе и расширить этот класс, либо реализовать метод как метод по умолчанию в интерфейсе. Использование суперкласса было бы более обычным способом сделать это.

Используя предоставленный вами код, вы можете сделать что-то вроде этого:

class Printer {

    protected void print(String listTitle, List<E> listToPrint) {
        StringBuilder string = new StringBuilder();
        string.append(listTitle);

        for (E request : listToPrint) {
            string.append("\n").append(request);
        }
}

затем расширить этот класс:

public class FundingRequests extends Printer implements RequestData<FundingRequest> {
        private TreeSet<FundingRequest> requests;

        FundingRequests() {
            this.requests = new TreeSet<>();
        }

        ...

        @Override
        public void printRequests() {
            print("",new ArrayList<>(requests));
        }

}

хотя это ограничит ваш класс только расширением этого класса. Лучшим вариантом было бы реализовать этот метод как открытый статический метод в классе, а затем использовать его следующим образом:

class Printer {

    public static void print(String listTitle, List<E> listToPrint) {
        StringBuilder string = new StringBuilder();
        string.append(listTitle);

        for (E request : listToPrint) {
            string.append("\n").append(request);
        }
    }
}

затем используйте метод:

public class FundingRequests implements RequestData<FundingRequest> {
    private TreeSet<FundingRequest> requests;

    FundingRequests() {
        this.requests = new TreeSet<>();
    }

    ...

    @Override
    public void printRequests() {
        Printer.print("",new ArrayList<>(requests));
    }
}

или, если вы действительно хотите сойти с ума, вы можете осуществить это с помощью абстрактного класса:

abstract class RequestData<E> {

    abstract void add(E newRequest);

    abstract List<E> getRequests();

    abstract List<E> getFulfilledRequests();

    abstract List<E> getUnfulfilledRequests();

    abstract void printRequests();

    abstract void printFulfilledRequests();

    abstract void printUnfulfilledRequests();

    protected void print(String listTitle, List<E> listToPrint) {
        StringBuilder string = new StringBuilder();
        string.append(listTitle);

        for (E request : listToPrint) {
            string.append("\n").append(request);
        }

        System.out.println(string);
    }

}

затем расширить этот класс:

public class FundingRequests extends RequestData<FundingRequest> {
        private TreeSet<FundingRequest> requests;

        FundingRequests() {
            this.requests = new TreeSet<>();
        }

        // implement the abstract methods

        @Override
        public void printRequests() {
            print("",new ArrayList<>(requests));
        }

}
0 голосов
/ 09 ноября 2018

Вы можете просто полностью извлечь этот метод print() или сделать его вложенным статическим классом.

public interface RequestData<E> {

    void add(E newRequest);

    List<E> getRequests();

    List<E> getFulfilledRequests();

    List<E> getUnfulfilledRequests();

    void printRequests();

    void printFulfilledRequests();

    void printUnfulfilledRequests();

    public static final class Printer {
        protected static <E> void print(String listTitle, List<E> listToPrint) {
            StringBuilder string = new StringBuilder();
            string.append(listTitle);

            for (E request : listToPrint) {
                string.append("\n").append(request);
            }

            System.out.println(string);
        }
    }
}


public class FundingRequests implements RequestData<FundingRequest> {
    private TreeSet<FundingRequest> requests;

    FundingRequests() {
        this.requests = new TreeSet<>();
    }

    ...

    @Override
    public void printRequests() {
        Printer.print("",new ArrayList<>(requests));
    }
}

Это позволяет вам поддерживать print() при protected доступности, но при этом будет открыт Printer вложенный статический класс, который ничего не делает с точки зрения public. Если можно сделать метод public, вы можете просто определить этот метод как public static (то есть служебный) метод.

0 голосов
/ 09 ноября 2018

Вы должны использовать защищенные модификаторы. Закрытые методы доступны только из одного класса, но не из дочерних классов.

...