Java 接口方法与类方法
在Java-8中,我们可以有一种方法,例如,以多种方式屏蔽字符串: 接口实现Java 接口方法与类方法,java,class,interface,java-8,Java,Class,Interface,Java 8,在Java-8中,我们可以有一种方法,例如,以多种方式屏蔽字符串: 接口实现 public interface StringUtil { static String maskString(String strText, int start, int end, char maskChar) throws Exception{ if( Strings.isNullOrEmpty(strText)) return "";
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);
}
}
现在可以通过类实现,如下所示
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);
}
}
问题:
在哪种情况下必须优先选择哪一种?到目前为止,我了解到接口
函数是不可通过模拟
进行测试的,因此我必须在接口函数上有一个包装函数-简而言之-它不是单元测试友好的,而且,由于是静态的
,所以不能重写接口方法
那么,如果你可以选择写一个函数?
,那么你还需要考虑其他用例,为了在接口中定义一个方法,你需要使用默认关键字。通常,方法不在接口中定义-这可能是类和接口之间最大的区别 现在,当您希望保证跨无关类共享功能时,可以使用接口。例如,Serializable
接口保证实现该接口的任何类都是Serializable
。我不打算解释“Serializable”在这里的含义,但其思想是,不要让数百个类在混乱的子类树中扩展抽象的Serializable类,只需实现Serializable,并使用多态性的功能将类称为Serializable
。查看此处,了解更多精彩信息:
在本例中,您需要的是StringUtil类,而不是StringUtil接口。因为StringUtil只包含一个实用程序方法,所以您还需要将此方法(maskString())
设为静态的 首先,为了在接口中定义方法,需要使用default关键字。通常,方法不在接口中定义-这可能是类和接口之间最大的区别
现在,当您希望保证跨无关类共享功能时,可以使用接口。例如,Serializable
接口保证实现该接口的任何类都是Serializable
。我不打算解释“Serializable”在这里的含义,但其思想是,不要让数百个类在混乱的子类树中扩展抽象的Serializable类,只需实现Serializable,并使用多态性的功能将类称为Serializable
。查看此处,了解更多精彩信息:
在本例中,您需要的是StringUtil类,而不是StringUtil接口。因为StringUtil只包含一个实用程序方法,所以您还需要将此方法(maskString())设为静态的 对于任何明确开发的实用程序,我建议使用类默认方法
有特殊用途。这些是实用方法,需要由供应商提供实施(记住?-接口是供应商和用户之间的合同
)
例如,如果您正在使用任何第三方库,并且某一天供应商引入了一个新的实用程序功能,那么要么所有客户都必须在界面中重写该方法,要么供应商添加一个静态默认方法。这样,新库的代码仍然向后兼容(在二进制代码级别
)
确切地说,功能接口的用法和用途在Oracle文档中有很好的解释,如下所示:-
默认方法使您能够向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性
更多信息,您可以阅读官方文档
此外,出于这个目的,在编写默认方法之前,您永远不需要在自己的终端测试默认方法。如果实用方法很复杂,就应该对其进行测试。这些实用程序当然可以进行集成测试。另外,正如您所说,您可以编写接口的简单实现并测试这些东西。这类似于测试抽象类
。阅读了解更多详细信息。对于任何明确开发的实用程序,我建议使用类默认方法
有特殊用途。这些是实用方法,需要由供应商提供实施(记住?-接口是供应商和用户之间的合同
)
例如,如果您正在使用任何第三方库,并且某一天供应商引入了一个新的实用程序功能,那么要么所有客户都必须在界面中重写该方法,要么供应商添加一个静态默认方法。这样,新库的代码仍然向后兼容(在二进制代码级别
)
确切地说,功能接口的用法和用途在Oracle文档中有很好的解释,如下所示:-
默认方法使您能够向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性
更多信息,您可以阅读官方文档
此外,出于这个目的,在编写默认方法之前,您永远不需要在自己的终端测试默认方法。如果实用方法很复杂,就应该对其进行测试。这些实用程序当然可以进行集成测试。另外,正如您所说,您可以编写接口的简单实现并测试这些东西。这类似于测试
抽象类
。阅读了解更多详细信息。对我来说,接口是契约式的,因此它不能绑定到任何实现。第一个,甚至你使用第二个,让它保持静态。你也可以将静态
用于第二个。什么dif
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);
}
}
StringUtil su = new StringUtil()
String mask = su.maskString("52418100", 2, 4, 'x')