为什么允许接口使用 "Default" 访问说明符?
Why is the "Default" access specifier allowed for interfaces?
由于 Java 中的接口具有默认为 public 的方法和常量,因此对我来说,具有默认(或无)访问说明符的接口有些矛盾,如下例所示,尽管默认情况下接口中的方法应该是 public 但接口在其定义的包之外的包中甚至不可见。
package com.anirudh.package1;
interface IAccessSpecifierInterfaceTest {
/**
*
* @param input
*/
void implementMe(String input);
}
package com.anirudh.package2;
public class TryingToImplementDefaultInterfaceFromOtherPackage implements IAccessSpecifierInterfaceTest {
}
TryingToImplementDefaultInterfaceFromOtherPackage 给出错误(无法解析 IAccessSpecifierTest
有谁知道任何需要默认访问界面的实际场景?为什么?
只要接口是包实现的一部分,而不是其 public API.
的一部分,它就可以受到包保护
虽然methods and fields是隐含的public,但从整体上防止对界面的访问仍然很有价值。
例如,假设您有一个可以解析和执行自定义脚本语言的包。解析是包内部的。抽象语法树中的所有节点都实现一个公共接口。但是该接口不是包的 public API 的一部分。可以进行包保护,防止在包外使用。
与保留东西的任何其他原因一样 "package protected"。
例如,假设您有一个方法调用另一个方法,该方法的参数指定在几种情况下应该做什么(最基本的示例:onSuccess
和 onError
)。您很可能会在 java 中使用接口实现它。
但是,这是供您个人和内部使用的。您不希望向外公开此接口。使用您的包的任何人都没有(或应该)访问有问题的方法,因此他们没有理由访问此接口。
解释场景的简短代码示例:
class DoingSomething {
void doSomething(IResponse response) {
if (/*do something*/) {
response.onSuccess();
} else {
response.onError();
}
}
}
class AskForSomething {
void ask() {
new DoingSomething().doSomething(new IResponse() {
void onSuccess() {
System.out.println("Success.");
}
void onError() {
System.err.println("error..");
}
});
}
}
interface IResponse {
void onSuccess();
void onError();
}
在这种情况下,DoingSomething
和 AskForSomething
是包保护的,因此 IResponse
也应该是包保护的,因为包外的任何人都不能访问任何一个接口或 类 / 方法。
具有包作用域的接口确实有它们的好处,但首先你必须想象,在什么情况下使用包作用域确实有意义。我唯一能想到的是可能会或不应该在包外使用的特定于包的实现。如果你能接受这种推理,你肯定会得出这样的结论,即所有设计模式都适用于这种情况,因此与包范围的接口确实有意义。
现在唯一要问的是,接口是做什么用的?简而言之,他们根据对实现该接口的 class 的期望来定义契约。由于合约是 public,即您希望方法及其签名可用,默认值只能是 public。
由于 Java 中的接口具有默认为 public 的方法和常量,因此对我来说,具有默认(或无)访问说明符的接口有些矛盾,如下例所示,尽管默认情况下接口中的方法应该是 public 但接口在其定义的包之外的包中甚至不可见。
package com.anirudh.package1;
interface IAccessSpecifierInterfaceTest {
/**
*
* @param input
*/
void implementMe(String input);
}
package com.anirudh.package2;
public class TryingToImplementDefaultInterfaceFromOtherPackage implements IAccessSpecifierInterfaceTest {
}
TryingToImplementDefaultInterfaceFromOtherPackage 给出错误(无法解析 IAccessSpecifierTest
有谁知道任何需要默认访问界面的实际场景?为什么?
只要接口是包实现的一部分,而不是其 public API.
的一部分,它就可以受到包保护虽然methods and fields是隐含的public,但从整体上防止对界面的访问仍然很有价值。
例如,假设您有一个可以解析和执行自定义脚本语言的包。解析是包内部的。抽象语法树中的所有节点都实现一个公共接口。但是该接口不是包的 public API 的一部分。可以进行包保护,防止在包外使用。
与保留东西的任何其他原因一样 "package protected"。
例如,假设您有一个方法调用另一个方法,该方法的参数指定在几种情况下应该做什么(最基本的示例:onSuccess
和 onError
)。您很可能会在 java 中使用接口实现它。
但是,这是供您个人和内部使用的。您不希望向外公开此接口。使用您的包的任何人都没有(或应该)访问有问题的方法,因此他们没有理由访问此接口。
解释场景的简短代码示例:
class DoingSomething {
void doSomething(IResponse response) {
if (/*do something*/) {
response.onSuccess();
} else {
response.onError();
}
}
}
class AskForSomething {
void ask() {
new DoingSomething().doSomething(new IResponse() {
void onSuccess() {
System.out.println("Success.");
}
void onError() {
System.err.println("error..");
}
});
}
}
interface IResponse {
void onSuccess();
void onError();
}
在这种情况下,DoingSomething
和 AskForSomething
是包保护的,因此 IResponse
也应该是包保护的,因为包外的任何人都不能访问任何一个接口或 类 / 方法。
具有包作用域的接口确实有它们的好处,但首先你必须想象,在什么情况下使用包作用域确实有意义。我唯一能想到的是可能会或不应该在包外使用的特定于包的实现。如果你能接受这种推理,你肯定会得出这样的结论,即所有设计模式都适用于这种情况,因此与包范围的接口确实有意义。
现在唯一要问的是,接口是做什么用的?简而言之,他们根据对实现该接口的 class 的期望来定义契约。由于合约是 public,即您希望方法及其签名可用,默认值只能是 public。