Java为什么不允许接口中的私有成员?有什么特别的原因吗?
Java为什么不允许接口中的私有成员?有什么特别的原因吗?
Answers:
没有办法实现这样的接口。 我强烈提出的一个问题的答案强烈表明,不可能(不从根本上改变规则)实现与私有方法的接口-这留下了为什么不允许保护和封装私有方法的问题。
class OuterClass
{
void run ( MyInterface x )
{
x . publicMethod ( ) ; // why not?
x . protectedMethod ( ) ; // why not?
x . packagePrivateMethod ( ) ; // why not?
x . privateMethod ( ) ; // why not?
}
interface MyInterface
{
public abstract void publicMethod ( ) ; // OK
protected abstract void protectedMethod ( ) ; // why not?
abstract void packagePrivateMethod ( ) ; // in interface default is public, but why not package private
private void privateMethod ( ) ; // impossible to implement
}
class MyImpl implements MyInterface
{
public void publicMethod ( ) { } // ok
protected void protectedMethod ( ) { } // no sweat
void packagePrivateMethod ( ) { } // no sweat
private void privateMethod ( ) { } // not happening
}
}
下面的代码应达到预期的效果。即使所有方法都是公共的,但只有公共方法才是有效的公共。受保护的方法得到有效保护。packagePrivateMethod实际上是packagePrivate。privateMethod实际上是私有的。
class WorkAround
{
void run ( MyPrivateInterface x )
{
x . publicMethod ( ) ;
x . protectedMethod ( ) ;
x . packagePrivateMethod ( ) ;
x . privateMethod ( ) ;
}
public interface MyPublicInterface { void publicMethod ( ) ; }
protected interface MyProtectedInterface extends MyPublicInterface { void protectedMethod ( ) ; }
interface MyPackagePrivateInterface extends MyProtectedInterface { void packagePrivateMethod ( ) ; }
private interface MyPrivateInterface extends MyPackagePrivateInterface { void privateMethod ( ) ; }
}
Java在Java 9的接口中允许私有方法。在默认的方法在Java中8这可能是多个默认方法想分享一些代码进行了介绍,那么这段代码可以被移动到一个私有方法不能暴露在外部世界。此错误已得到修复,并且从JDK 9 build 54开始,已经恢复了对私有接口方法的编译器支持。
public interface IData{
default void processData(int data) {
validate(data);
// do some work with it
}
default void consumeData(int data) {
validate(data);
// do some work with it
}
private void validate(int data) {
// validate data
}
}
这是因为它们将毫无用处。
将无法调用私有方法。
私有成员是实现细节。接口是关于类可以担当的公共角色。
私有字段不会完全没有用,因为其他字段和内部类可以访问它们。
但是,即使在嵌套类中也无法实现私有方法,这使它们几乎毫无用处。您可以使用反射来阅读它们,但这只是一个边缘情况。
是的,不能那样做。对于所有评论为什么不应该评论的人:
想象一下,我拥有使用接口I的ClassA。ClassB扩展了Class A,因此也继承了A中的所有接口方法。
现在,假设我想要在A类中使用私有方法,但也希望通过合同为其他类定义该方法(也许是C类,不一定扩展B类或A类)。
也许对于“初始化”方法,我想对所有使用I接口的类。但是显然我不希望初始化方法是公开的...。因为它只能使用一次,或者在类认为必要时使用,而不仅仅是因为您想随意使用它。
唯一的解决方案是一种解决方法,或者简单地通过将init方法强制进入类本身而不使用接口。
我可以肯定地理解原因,但是有时它仍然可以派上用场。显然,Oracle同意他们在JDK 9中允许私有接口方法的观点。
无论如何,我所做的就是放置一个简单的布尔变量,这样在设置一次之后,接口方法(应该是私有的)可以被标记为true(初始化= true)。然后,当再次调用该方法时,它什么也不做。这样,接口方法可以实现为公共方法,但是由于(我的类的)构造函数首先调用该方法,因此将变量设置为true,因此无法再次调用该方法。
否则,如果您只希望类的内部工作使用它,则必须尝试其他解决方法....也许方法本身会在使用它时将其标志设置为on和off。当标志为false时,该方法不执行任何操作(这将是有人从类外部调用它的时候)。但是,当类自己的方法调用它时,它们很快将标志设置为true,然后调用该方法,然后将标志设置为false?
到底有点静音。就目前而言,将私有类简单地放置到类本身中并完全切断接口可能更好。