2011-08-26 101 views
179

考虑这样一个例子(编译Java中)Java的抽象接口

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

为什么需要一个接口是“申报”抽象?是否有其他适用于抽象接口的规则?


最后:如果abstract已过时,它为什么包含在Java中?抽象界面有历史吗?

+0

可能重复[为什么要声明一个接口为抽象?](http://stackoverflow.com/questions/2134200/why-declare-an-interface-as-abstract ) – Thilo

+5

考虑到“*最后:.... *”部分不重复。 – aioobe

+0

这个相关的问题引用了一个真实的例子:http://stackoverflow.com/questions/4380796/what-is-public-abstract-interface-in-java/4381308#4381308 – Raedwald

回答

415

为什么需要将接口“声明”为抽象?

不是。

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

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

接口和他们的方法隐含abstract并补充说,修改没什么区别。

是否有其他规则适用于抽象接口?

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

如果abstract已经过时,为什么它包含在Java中?抽象界面有历史吗?

有趣的问题。我挖出了第一个版的JLS,甚至在那里它说的是"This modifier is obsolete and should not be used in new Java programs"

好吧,挖进一步 ...打无数断开链接后,我设法找到原Oak 0.2Specification(或“手动”)的副本。我必须说非常有趣的阅读,总共只有38页! :-)

根据第5,接口,它提供了以下示例:

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

而且在余量它说

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

假设=0得到了由abstract关键字替换,我怀疑abstract在某一点强制性的接口方法!


相关文章:Java: Abstract interfaces and abstract interface methods

+73

+1挖,我也找不到原因。 :) –

+111

+1努力的漂亮ascii艺术:) – Bohemian

+2

但抽象本身并没有过时,或?它已经过时了,但仍然有抽象类和方法。 –

35

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

见JLS在此:

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

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

而且

9.4抽象方法声明

[...]

为了与旧版本的Java平台的兼容性,它是 允许但不鼓励,作为事的样式,重复地为 指定在接口中声明的方法的抽象修饰符。

作为样式,允许但强烈不鼓励 冗余地指定接口方法的公共修饰符。

+5

给JLS:作为一种风格,允许但强烈劝阻冗余地写出两个相同含义和几乎相同字词的句子...... – n611x007

12

没有必要声明接口摘要。

就像声明所有这些方法是公共的(它们已经是接口是公共的)或抽象的(它们已经在接口中)是多余的。

虽然没有人阻止你。

其他的事情你可以明确说明,但并不需要:

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

是否有其他规则适用于抽象接口?

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

+2

显然,如果接口本身就是公开的方法是包私有的。 – Thilo

2

这是没有必要的。这是一种语言的怪癖。

2

这不是必需的,因为接口默认是抽象的,因为接口中的所有方法都是抽象的。

-3

抽象接口并不像每个人似乎至少在理论上所说的那样多余。

一个接口可以像Class一样扩展。如果你为你的应用程序设计一个接口层次结构,你可能会有一个'基础'接口,你可以扩展其他接口,但不希望作为一个对象本身。

例子:

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

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

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

你不想一类来实现MyBaseInterface,只有另外两个,MMyDog和MyBoat,但两个接口共享MyBaseInterface接口,所以才有了“名”属性。

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

在这种情况下,它实际上只是一个“标记”,它向接口的实现者发出信号,表示它不是被设计成独立实现的。我应该指出一个编译器(至少是我试过的sun/ora 1.6)编译一个实现抽象接口的类。

+3

我相信你绝对误解了我的问题。 –

+3

我不同意这个推理。我认为每个接口都必须提供完全可用的功能集,因此每个接口都可以自行实现。 也没有理由让编译器拒绝编译一个实现了明确声明为抽象的接口的类,因为所有接口都已经隐式抽象。这将完全改变“抽象”关键字的含义。 – BladeCoder

6

请注意,在春季它没有学术意义。 抽象界面对开发者是一个警告,不要将它用于@Autowired。 我希望春/日本@Autowired将看这个属性,并警告/失败这种用法。

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

+0

+1好打,我看了一个非易失sessionbean注射的分离。也许我可以使用findbugs/checkstyle作为规则.... –

-3

好'抽象接口'是一个词法构造:http://en.wikipedia.org/wiki/Lexical_analysis

它是编译器要求的,你也可以写interface

那么不要太过分的词汇结构的语言,因为他们可能会把它放在那里解决一些编译歧义,这在编译过程中被称为特殊情况或为了一些向后兼容性,尝试专注于核心词汇构造。

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

接口是一种纯粹的抽象数据类型,它表示正在捕获或表示的对象的特征。

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

如果您的具体类没有实现所有的功能,它会再次变得抽象,因为您有一个思想或想法或抽象的实现,但它不完整,您可以通过abstract类指定它。

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

所以图案是

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

这个答案根本不回答我的问题。另外'''它接缝就像你是Java新手'。真的吗? –

+0

“abstract is obsolete” – Manish

+0

(1)“abstract is obsolete” - >如果他们删除它并且编译器停止识别它,那么以前版本的源代码使用“抽象接口”不会在新版本中编译..他们需要保持向后兼容性。当你定义抽象接口时,接口关键字的含义与它一起被“卡住”,这对于他们提供的有经验的程序员快捷键“界面”..你的问题是类似于我= i + 1 ==>我++ ..选择是你的你选择的:D – Manish