Java抽象接口


197

考虑一个示例(在Java中编译)

public abstract interface Interface {
    public void interfacing();
    public abstract boolean interfacing(boolean really);
}

为什么必须将接口“声明”为抽象的?还有其他适用于抽象接口的规则吗?


最后:如果abstract过时,为什么将它包含在Java中?有抽象接口的历史吗?



5
考虑到“ Final:.... ”部分,不能重复。
aioobe 2011年

这个相关的问题引用了一个真实的例子:stackoverflow.com/questions/4380796/…–
Raedwald

1
为什么在“提取接口”时Eclipse在默认情况下添加“抽象”?
ModdyFire 2014年

@ModdyFire,请详细说明?
Buhake Sindi 2014年

Answers:


447

为什么必须将接口“声明”为抽象的?

不是。

public abstract interface Interface {
       \___.__/
           |
           '----> Neither this...

    public void interfacing();
    public abstract boolean interfacing(boolean really);
           \___.__/
               |
               '----> nor this, are necessary.
}

接口及其方法是隐式的abstract,添加该修饰符没有区别。

还有其他适用于抽象接口的规则吗?

不,适用相同的规则。该方法必须由任何(具体)实现类来实现。

如果抽象已经过时,为什么它包含在Java中?有抽象接口的历史吗?

有趣的问题。我挖出了第一 JLS的版本,甚至还有它说:“这个修改是过时的,不应该在新的Java程序中使用”

好的,进一步挖掘 ...碰到许多断开的链接后,我设法找到了原始的Oak 0.2 规范(或“手册”)的副本。我必须说非常有趣的阅读,总共只有38页!:-)

在第5节“接口”下,提供以下示例:

public interface Storing {
    void freezeDry(Stream s) = 0;
    void reconstitute(Stream s) = 0;
}

边上说

将来,接口中声明方法的“ = 0”部分可能会消失。

假设=0abstract关键字替换,我怀疑这abstract在某种程度上对于接口方法是必需的!


相关文章:Java:抽象接口和抽象接口方法


3
但是抽象本身不是过时的,还是?接口已经过时了,但是仍然有抽象类和方法。
user85421 2011年

谢谢;-)我想我终于确定了起源,甚至允许abstract使用接口方法。
aioobe 2011年

13
哇。因此,“按设计”已过时。那些JLS设计师真的总是非常害怕破坏某些东西,甚至破坏那些从未发布过的东西……:-)
Lukas Eder

@aioobe,您必须是我们不知道的Google网络爬虫...大声笑
Buhake Sindi 2011年

18
顺便说一句。接口声明中的方法上也不需要“公共” ...它们始终是公共的。
REC

37

就像public接口方法一样,这不是必需的,而是可选的。

参见JLS:

http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html

9.1.1.1抽象接口每个接口都是隐式抽象的。该修饰符已过时,不应在新程序中使用。

9.4抽象方法声明

[...]

为了与Java平台的较早版本兼容,出于样式考虑,允许但不鼓励为接口中声明的方法冗余地指定abstract修饰符。

允许(但强烈建议您避免样式)为接口方法多余地指定public修饰符。


7
to JLS:允许但强烈不建议在风格上重复写两个具有相同含义和几乎准确措辞的句子,彼此相邻……
n611x007 2013年

11

不必声明接口抽象。

就像将所有这些方法声明为公共(如果接口是公共的,它们已经是)或抽象(它们已经在接口中的)那样都是多余的。

但是,没有人阻止您。

您可以明确声明的其他内容,但不需要:

  • 在构造函数的第一行调用super()
  • extends Object
  • 实现继承的接口

还有其他适用于抽象接口的规则吗?

接口已经是“抽象的”。再次应用该关键字绝对没有区别。


2
显然,如果接口本身是程序包私有的,则这些方法甚至是公共的。
Thilo

7

请注意,在春季它没有学术意义。抽象接口向开发人员发出警告,请不要将其用于@Autowired。我希望spring / eclipse @Autowired会查看此属性,并警告/失败有关此属性的用法。

一个真实的例子:@Transnational下的@Service代理到@Repository需要使用相同的基本方法,但是由于,它们应该使用不同的接口来扩展此抽象接口@Autowired。(我将此称为XXXSpec接口)


+1命中率很高,我很想寻找一个不可钝化的sessionbean注入。也许我可以使用findbugs / checkstyle作为规则
。...– Grim



2

不必要,因为默认情况下接口是抽象的,因为接口中的所有方法都是抽象的。


-2

至少从理论上讲,抽象接口并不像每个人都说的那样多余。

可以像类一样扩展接口。如果您为应用程序设计接口层次结构,则可能会有一个“基础”接口,您可以从中扩展其他接口,但不希望将其本身作为对象。

例:

public abstract interface MyBaseInterface {
    public String getName();
}

public interface MyBoat extends MyBaseInterface {
    public String getMastSize();
}

public interface MyDog extends MyBaseInterface {
    public long tinsOfFoodPerDay();
}

您不希望Class实现MyBaseInterface,仅希望其他两个实现MMyDog和MyBoat,但是两个接口都共享MyBaseInterface接口,因此具有“名称”属性。

我知道它有点学术,但是我认为有些人可能会觉得它很有趣。:-)

在这种情况下,它实际上只是一个“标记”,用于向接口的实现者发出信号,告知它并非旨在单独实现。我应该指出一个编译器(至少是我尝试过的sun / ora 1.6)编译了一个实现抽象接口的类。


3
我相信您绝对误解了我的问题。
Buhake Sindi

3
我不同意这种推理。我认为每个接口都必须提供完全可用的功能集,因此每个接口都可以单独实现。同样,编译器也没有理由拒绝编译实现显式声明为抽象的接口的类,因为所有接口已经隐式抽象。那将完全改变“抽象”关键字的含义。
BladeCoder 2014年

-3

“抽象接口”是一个词汇构造:http : //en.wikipedia.org/wiki/Lexical_analysis

编译器需要它,您也可以编写interface

好吧,不要过多地关注语言的Lexical构造,因为他们可能会把它放在这里以解决某些编译歧义,这在编译过程中或为向后兼容而被称为特殊情况,请尝试着眼于核心Lexical构造。

接口的本质是捕获一些抽象概念(思想/思想/高阶思维等),其实现可能会有所不同……也就是说,可能有多种实现。

接口是纯抽象数据类型,表示它正在捕获或表示的对象的功能。

要素可以用空间或时间来表示。当它们由空间(内存存储)表示时,这意味着您的具体类将实现一个字段以及将对该字段或时间进行操作的方法/方法,这意味着实现该功能的任务纯粹是计算性的(需要更多的cpu时钟进行处理),因此您需要在空间和时间之间进行权衡。

如果您的具体类没有实现所有功能,则由于您已经实现了您的思想,观念或抽象性,但是又不完整,那么您又会变得抽象,您可以按abstract类指定它。

一个具体的类将是一个类/一组类,它将完全捕获您要捕获的类XYZ的抽象性。

所以模式是

Interface--->Abstract class/Abstract classes(depends)-->Concrete class

1
这个答案根本无法回答我的问题。也"It seams like you are new to Java。真?
Buhake Sindi 2014年

“摘要已过时”
Manish 2014年

(1)“抽象方法已过时”->如果将其删除,并且编译器停止识别它,则使用“抽象接口”的以前版本的源代码将不会在较新的版本中进行编译..他们需要保持向后兼容性。当您定义抽象接口时,interface关键字的含义与“ abstract”一起使用,这是更简洁的版本,但是对于像您这样的经验丰富的程序员,他们提供了快捷方式“ interface” ..您的问题类似于i = i + 1 == > i ++ ..选择就是您的选择:D
Manish

查看接受的答案。我知道abstract界面已过时。我想知道为什么它仍然可以接受,以及abstract界面背后的历史是什么。您正在给我关于抽象与接口的Java 101指南。
Buhake Sindi

它不是词汇构造。这是语法。在语义上是多余的。它不是“编译器必需的”。关于空间/时间的部分只是胡闹。这些废话都无法回答所提出的问题。不要对非代码文本使用代码格式。
罗恩侯爵
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.