简体   繁体   English

接口方法与类方法

[英]interfaces methods vs classes methods

in Java-8, we can have a method, say, for masking a string , in multiple ways : 在Java-8中,我们可以使用多种方法来屏蔽字符串

Interface Implementation 接口实现

public interface StringUtil {
    static String maskString(String strText, int start, int end, char maskChar)
            throws Exception{

        if( Strings.isNullOrEmpty(strText))
            return "";

        if(start < 0)
            start = 0;

        if( end > strText.length() )
            end = strText.length();

        if(start > end)
            throw new Exception("End index cannot be greater than start index");

        int maskLength = end - start;

        if(maskLength == 0)
            return strText;

        StringBuilder sbMaskString = new StringBuilder(maskLength);

        for(int i = 0; i < maskLength; i++){
            sbMaskString.append(maskChar);
        }

        return strText.substring(0, start)
                + sbMaskString.toString()
                + strText.substring(start + maskLength);
    }
}

this can be accessed via: 可以通过以下方式访问:

StringUtil.maskString("52418100", 2, 4, 'x')

Now same can be implemented via classes as below 现在可以通过以下类实现相同的功能

public class StringUtil {

    public String maskString(String strText, int start, int end, char maskChar)
                throws Exception{

            if( Strings.isNullOrEmpty(strText))
                return "";

            if(start < 0)
                start = 0;

            if( end > strText.length() )
                end = strText.length();

            if(start > end)
                throw new Exception("End index cannot be greater than start index");

            int maskLength = end - start;

            if(maskLength == 0)
                return strText;

            StringBuilder sbMaskString = new StringBuilder(maskLength);

            for(int i = 0; i < maskLength; i++){
                sbMaskString.append(maskChar);
            }

            return strText.substring(0, start)
                    + sbMaskString.toString()
                    + strText.substring(start + maskLength);
    }
}

this can be accessed as : 可以通过以下方式访问:

StringUtil su = new StringUtil()
String mask = su.maskString("52418100", 2, 4, 'x')

Question: 题:

Which has to be preferred in which case? 在这种情况下,哪个优先? So far I understand that interface function are non-testable via mock , so I have to have a wrapper function on top of my interface function - in nutshell - its not unit test friendly and also, being static , you can not override interface methods. 到目前为止,我知道interface函数是无法通过mock测试的,因此我必须在接口函数之上拥有一个包装器函数(简而言之) ,它不适合单元测试,并且由于是static ,因此无法覆盖接口方法。

So what other use cases do you consider, if, having an option to write a function? 那么,如果可以选择编写函数,您还考虑其他哪些用例?

For any utility developed explicitly I recommend using a class. 对于任何明确开发的实用程序,我建议使用一个类。 Default methods in java have a special purpose. Java中的Default methods具有特殊目的。 These are intended to be utility methods for which implementation needs to be given from vendor ( Remember? - An interface is a contract between Vendor and User ). 这些旨在用作实用程序方法,需要从供应商那里获得实现( 记住吗? - An interface is a contract between Vendor and User )。

For example , if you are using any third party library and a day comes that vendor introduces a new utility feature, then either all the customers have to override that method inside the interface or it's just vendor adds a static default method. 例如 ,如果您正在使用任何第三方库,而供应商又有一天引入了新的实用程序功能,则要么所有客户都必须在界面中覆盖该方法,要么仅仅是供应商添加了静态默认方法。 This way the code with the new library is still backwards compatible ( at binary code level ). 这样,带有新库的代码仍然向后兼容( at binary code level )。

Precisely, the usage & purpose of a functional interface is well explained in Oracle documentation as below:- 准确的说,功能文档的用法和目的在Oracle文档中有很好的解释,如下所示:

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. 默认方法使您可以向库的接口添加新功能,并确保与为这些接口的较早版本编写的代码二进制兼容。

For more, you could read the official documentation here . 有关更多信息,您可以在此处阅读官方文档。

Also, given this purpose, there is never a requirement to test default methods at your end until you are the one writing such method. 同样,鉴于此目的,除非您是编写此类方法的人,否则最终无需测试默认方法。 A utility method should be tested if it's complex. 如果实用程序方法很复杂,则应进行测试。 These utilities for sure could be integration tested. 这些工具肯定可以进行集成测试。 Also, as you said you could write a simple implementation of the interface and test the things. 而且,正如您所说的,您可以编写接口的简单实现并测试事物。 This is similar to testing a abstract class . 这类似于测试abstract class Read here for more details. 在此处阅读更多信息。

First, in order to define a method in an interface, you need to use the default keyword. 首先,为了在接口中定义方法,您需要使用default关键字。 Normally, methods are not defined in interfaces - this is probably the biggest difference between classes and interfaces. 通常,方法未在接口中定义-这可能是类和接口之间的最大区别。

Now, you use an interface when you want to GUARANTEE shared functionality across unrelated classes. 现在,当您想保证不相关的类之间共享功能时,可以使用一个接口。 For example, the Serializable interface guarantees that ANY class implementing this interface is Serializable . 例如, Serializable接口保证实现此接口的任何类都是Serializable I'm not going to explain what "Serializable" means here, but the idea is that instead of having hundreds of classes extend an abstract Serializable class in a messy tree of subclasses, you can simply implement Serializable and use the Power of Polymorphism to refer to your class as a Serializable . 我在这里不打算解释“ Serializable”的含义,但是它的想法是,不是让数百个类在一个杂乱的子类树中扩展一个抽象的Serializable类,您可以简单地实现Serializable并使用Polymorphism的功能进行引用作为类Serializable Look here for more awesome info: https://www.tutorialspoint.com/java/java_interfaces.htm 在这里查看更多真棒信息: https : //www.tutorialspoint.com/java/java_interfaces.htm

In your case, you want a StringUtil class, not a StringUtil interface. 在您的情况下,您需要一个StringUtil类,而不是StringUtil接口。 Because StringUtil only contains a utility method, you also want to make this method (maskString()) static . 由于StringUtil仅包含一个实用程序方法,因此您还希望将此方法(maskString())设置为static

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

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