为什么Java不允许私有成员进入接口?

时间:2012-04-16 06:35:13

标签: java

为什么Java不允许私有成员进入界面?有什么特别的原因吗?

13 个答案:

答案 0 :(得分:82)

来自Java Language Spec, (Access Control)

  

" Java编程语言提供了访问控制机制,   防止包或类的用户依赖   该包或类的实施的不必要细节。"

访问控制就是隐藏实现细节。接口没有隐藏的实现。

答案 1 :(得分:41)

在Java 9中,接口中的私有方法是可能的。

Java 9 specifications

  

javac编译团队很高兴宣布编译器的可用性   支持私人   接口中的方法以9 b54构建的JDK开头。

答案 2 :(得分:14)

私有接口方法是Java 9的一部分,是JEP-213的一部分。由于Java 8中的接口可以具有default methods,因此私有方法允许多个默认方法使用共享私有方法。

答案 3 :(得分:11)

从Java 8开始,接口可以使用默认方法,从Java 9开始,允许接口具有私有方法,这些方法只能通过同一接口中的默认方法访问。

答案 4 :(得分:9)

接口用于描述由实现接口的任何类提供的API。由于其定义中的接口没有状态,因此不使用声明字段成员。

答案 5 :(得分:7)

没有办法实现这样的接口。 An answer to a question I posed强烈建议用私有方法实现接口是不可能的(没有根本改变规则) - 这就留下了为什么不允许使用protected和package私有方法的问题。

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

答案 6 :(得分:6)

根据Java编程语言,private members的范围仅限于声明它的class,并且只能通过class的方法访问。但是inteface没有方法体,因此不会在interface内声明私有成员。

答案 7 :(得分:3)

因为它们没用。

无法调用私有方法。

私有成员是一个实现细节。接口是关于类可以承担的公共角色。

答案 8 :(得分:3)

Java允许Java 9中的接口中的私有方法。在Java 8中引入了default methods。有可能多个默认方法想要共享一些代码,然后可以将此代码移动到私有方法而不将其暴露给外部世界。这个bug已得到修复,并从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
   }
}

答案 9 :(得分:2)

私有字段不会完全无用,因为其他字段和内部类可以访问它们。

然而,即使在嵌套类中也无法实现私有方法,这使得它们几乎无用。你可以使用反射来阅读它们,但这只是一个边缘情况。

答案 10 :(得分:1)

私人会员在界面中没有意义。接口是一种使用已定义方法访问类的方法,您无需查看该类的内部。

私人成员不同意这一点。

答案 11 :(得分:0)

  

声明为private的类的成员不会继承   该类的子类。仅声明的类的成员   protected或public由包中声明的子类继承   除了宣布上课的那个。

Source

所以你在一个可以使用那个私有的非可继承字段的接口中没有任何工作方法,那为什么它应该存在呢?

答案 12 :(得分:0)

是的,不能那样做。对于那些评论为什么不应该这样做的人:

想象一下,我有A类,它使用接口I. B类,扩展了A类,因此也继承了A中的所有接口方法。

现在,想象一下我想在A类中使用私有方法,但是也希望它为其他类合同定义(也许是C类,它不一定扩展为B类或A类)。

也许对于“初始化”方法,我想要使用I接口的所有类。但显然我不希望初始化方法公开....因为它应该只使用一次,或者在课程认为必要的时候,不仅仅是因为你想要全部使用它。

唯一的解决方案是解决方法,或者只是在没有接口的情况下将init方法强制转换为类。

我理解的原因当然不是,但是,它有时会派上用场。很明显,Oracle同意他们在JDK 9中允许私有接口方法。

无论如何,我所做的是放置一个简单的布尔变量,这样接口方法(应该是私有的)在设置一次后可以标记为true(initialized = true)。然后当再次调用时,该方法根本无效。这样接口方法可以实现为public,但由于构造函数(我的类)首先调用该方法,因此将变量设置为true,因此无法再次调用它。

否则,如果您只希望类的内部工作方式使用它,则必须尝试不同的解决方法....也许方法本身在使用它时设置打开和关闭标志。当标志为false时,该方法不执行任何操作(这将是有人从类外部调用它时)。但是,当类自己的方法调用它时,它们会快速将标志设置为true,然后调用该方法,然后将标志设置为false ??

最后是一种静音。现在可能只是简单地将私有类放入类本身并完全切断接口。