简体   繁体   English

您如何使用界面的私有方法?

[英]How do you use your interface's private methods?

I'm having trouble using a private method I had implemented within my interface. 我在使用在接口中实现的私有方法时遇到了麻烦。

I implemented a print(string, list) method privately in my RequestData interface, to hide implementation as I don't want it to be called except by the class' other print methods - but I included it in the interface because it's going to be the same with each implementing class. 我在RequestData接口中私下实现了一个print(string, list)方法,以隐藏实现,因为我不希望被类的其他打印方法调用,但是我将其包含在接口中,因为它将被每个实现类都一样。

Problem is, when I try to use the print method from my FundingRequests , which implements the RequestData interface, it shows the error - the print method's access in the RequestData interface is private, so it can't be found. 问题是,当我尝试使用print从我的方法FundingRequests ,它实现RequestData界面,它显示的错误-的print方法在访问RequestData接口是私有的,所以它不能被发现。

Well... how are you supposed to use an interface's private methods if they are not accessible from within the implementing classes? 好吧...如果无法从实现类中访问接口的私有方法,应该如何使用呢?

Is this a bug, or am I misunderstanding Interfaces? 这是一个错误,还是我误解了接口?

Interface: 接口:

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

}

Offending class & methods: 令人反感的课程和方法:

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

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

        ...

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

}

Private methods were provided as a feature to Java interfaces to help write default methods in interfaces without re-using code. 专用方法作为Java接口的功能提供,可帮助在接口中编写默认方法而无需重新使用代码。 They were not intended to be used for implementation inheritance. 它们不打算用于实现继承。

If you want to inherit and use implemented methods, such as what you attempted here: 如果要继承和使用实现的方法,例如您在此处尝试的方法:

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

you want to either implement the method in a super class and extend that class, or implement the method as a default method in an interface. 您要在超类中实现该方法并扩展该类,或者要将该方法作为接口中的默认方法实现。 Using a super class would be the more conventional way to do this. 使用超类将是更常规的方法。

Using the code you provided, you could do something like this: 使用您提供的代码,您可以执行以下操作:

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

then extend that class: 然后扩展该类:

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

}

although that would limit your class to only extending that class. 尽管那会将您的课程限制为仅扩展该课程。 The better pattern would be to implement that method as a public static method in a class, then use it, like this: 更好的模式是将该方法实现为类中的公共静态方法,然后使用它,如下所示:

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

then use the method: 然后使用方法:

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

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

    ...

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

or, if you really want to go crazy, you can pull this off with an abstract class: 或者,如果您真的想发疯,则可以使用抽象类来实现:

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

}

then extend that class: 然后扩展该类:

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

}

You can simply pull out that print() method totally, or make it a nested static class. 您可以简单地完全退出该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));
    }
}

This allows you to keep print() at protected accessibility, but it would expose Printer nested static class, which does nothing from a public perspective. 这样可以使print()保持protected可访问性,但是它将公开Printer嵌套的静态类,从public角度看,它什么也没做。 If it is fine to make the method public , you can simply define that method as a public static (ie an utility) method. 如果可以将方法设为public ,则可以简单地将该方法定义为public static (即实用程序)方法。

You should use protected modifiers. 您应该使用受保护的修饰符。 Private methods are only accessible from the same class, not by child classes. 私有方法只能从同一类访问,而子类不能访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM