为什么我的内部类中没有接口?他们为什么固有static
?对不起,如果这是一个愚蠢的问题,我已经尽力一次又一次谷歌这一点,但我似乎无法将它包裹起来。为什么我不能在内部类/本地类中声明这些?
另外,作为一个确认,我们可以在接口中拥有静态最终变量的原因是因为它们没有指定状态或任何类型的实现吗?如果我们丢失static
并仅使用最终版本,我们需要一个没有意义的实例,因为您无法实例化一个接口。对不起,我真的很困惑,我知道我应该提出另一个问题,但我认为这两个问题有些相关。
答案 0 :(得分:5)
考虑 static 的含义 - "与特定实例无关"。因此,正如您所指出的,static
类Foo
字段是一个不属于任何Foo
实例的字段,而是属于Foo
class 本身。
现在想想接口是什么 - 它是一个契约,一个实现它的类承诺提供的方法列表。另一种思考方式是接口是一组与特定类无关的方法。 - 任何类都可以实现它,只要它提供这些方法即可。
因此,如果一个接口与任何特定类没有关系,那么很明显一个接口与一个类的实例无关 - 对吗?
*注意,正如@Owlstead所指出的,有一些方法可以在类中定义接口。但是,为了围绕界面(这似乎是你正在进行的工作)包裹你的头脑,我现在会忽略这些可能性,因为它们会分散注意力,并且可能会模糊界面的目的。
答案 1 :(得分:4)
为什么我的内部类中没有接口?
因为接口是隐式静态的:JLS §8.5.1:
成员接口是隐式静态的(第9.1.1节)。允许声明成员接口冗余地指定静态修饰符。
并且你不能在内部类中使用非最终静态。
为什么它们是静态的?
因为这是他们设计的方式。
为什么我不能在内部类/本地类中声明这些?
因为它们是隐含的。
我们可以在接口中拥有静态最终变量的原因是因为它们没有指定状态或任何类型的实现权限吗?
右。
如果我们失去静态而只使用最终版,我们需要一个实例
右。
这没有任何意义,因为你无法实例化一个接口。
是的,你可以。您可以实例化实现该接口的类,也可以实例化其方法本地匿名实现。这里真正的问题是接口的多重继承。
答案 2 :(得分:3)
为什么他们[接口]固有
static
?
static
和非static
嵌套类之间的区别在于它们的实例是否具有对封闭实例(包含类的)的隐式引用,以及至于包含范围的局部变量。在Java 8之前,接口无法使用此类隐式引用,因为接口无法初始化任何非静态字段或提供任何方法实现。 (它仍然无法初始化非静态字段,但现在它可以提供默认方法实现。)因此,在Java 8之前,非static
嵌套接口没有任何意义。
此外,从实现的角度来看,这些隐式引用是作为内部类的额外字段实现的,它们还需要额外的内部类构造函数的参数(以初始化这些字段)。接口没有字段或构造函数,因此没有办法实现它。
(注意:我通常不建议尝试在实现方面理解语言设计决策,因为单个语言功能可以有许多不同的正确实现。但我认为这是理解实现有助于理解的一种情况规范,因此是前一段。)
答案 3 :(得分:0)
你不能在内部类中有一个接口,因为内部类只存在于“外部类”实例的上下文中。由于这种情况,您的界面实际上是非静态的。
但是,您可以在嵌套类中使用接口。见@owlstead答案。通过将'static'关键字放在'内部类'的声明上,它成为一流的公民,可以从外部类外部引用,并且(大多数)独立于外部类的上下文。嵌套类可以在外部类之外实例化;内部阶级不能。