为什么要将接口声明为抽象的?

53

声明一个接口为抽象的意义在哪里?同样,对于接口方法也是这样。它有什么意义吗?

例如:

public abstract interface Presenter {
 public abstract void go(final HasWidgets container);
}
11个回答

71
你发布代码块的来源是哪里,是从旧的Java代码库中吗?
这是JLS的说法: 9.1.1.1 抽象接口:
每个接口都是隐式抽象的。这个修饰符已经过时,不应该在新程序中使用。 9.4 抽象方法声明:
为了与早期版本的Java平台兼容,允许但不鼓励在接口中申明的方法中冗余指定抽象修饰符,这是一种风格问题。

2
@Sudhir,我在谷歌上搜索了你发布的代码块,发现了这个邮件线程,其中讨论了同样的问题: http://osdir.com/ml/Google-Web-Toolkit/2010-01/msg00452.html 还可以看看这个链接: http://osdir.com/ml/Google-Web-Toolkit/2010-01/msg00516.html,其中提到了可能的用法解释。(换句话说:最初作为抽象类开始的东西可能已经被更改为接口,而早期的修饰符没有被删除) - sateesh
嗯...那就可以解释了。 - Sudhir Jonathan
3
该死的Oracle!!! 这个链接只是重定向到Oracle Java年表网站,非常符合公司形象,甚至不关心历史证据一旦你获取了它。 - IronBlossom
@sateesh 你的意思是 HibernateSessionFactory 写得很老旧吗? - Dheeraj Upadhyay
我在一个由JDK 11编译的代码中看到了这个。 - Seyed Ali Roshan

29

即使未被声明为抽象的,接口和接口方法也是隐式的抽象的。因此,没有必要明确指定。


4
所有接口方法也隐式地具有 public 访问修饰符,因此将它们声明为 public 是多余的。 - matt b
同样适用于方法中的“public”:它是隐式的,不需要。 - Joachim Sauer
"public" 让它更明确,对于可读性来说我认为很好。在这种情况下,抽象是无意义的。 - Keith Rousseau
1
@Keith:不是要吵架,但是这里的方法前面的“public”和“abstract”有什么不同?两者都是隐式的,无法更改。为什么一个要写而另一个不用写呢? - Joachim Sauer
1
@Joachim:我认为并非所有开发人员都会意识到接口默认是公共的。我一直认为充分限定某个东西是公共的/受保护的/私有的是一个好习惯。根据接口的定义,它是抽象的。 - Keith Rousseau

4
没有区别 - 接口和接口方法始终是抽象的,但您不必添加修饰符(接口方法始终是公共的,因此您也不需要 public 修饰符)。
来自JLS

9.1.1.1 抽象接口

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


3
通常情况下,您不需要将接口或其方法声明为抽象的,它们会隐式地被认为是抽象的。这些方法也是公共的,所以您也可以省略它们。 :-)

1

“为什么要将接口声明为抽象的?” -我也有同样的疑问,认为抽象是多余的。但当我看到Java 1.8中的Map接口时,不得不重新思考。也许这在Java中需要更改。

//  (version 1.8 : 52.0, no super bit)
// Signature: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;
public abstract interface java.util.Map {

  // Method descriptor #1 ()I
  public abstract int size();
}

1

0

一个接口方法的抽象修饰符总是冗余的,public修饰符也是如此。

对于一个接口本身来说,抽象修饰符可能出于一个严格的技术原因而是多余的,因为接口永远不能使用new运算符来实例化,并且通过反射访问时,接口将始终是抽象的。

然而,声明接口为抽象的可能存在语义上的原因(这也得到了各种UML工具的支持):您可能希望表达一个接口是显式地声明为抽象的,以便非抽象类不能直接实现该接口,但只能通过子接口间接实现。例如,您可能认为接口Node在语义上是抽象的,而扩展Node的子接口Folder和File在语义上并不是抽象的。您永远不会拥有只是Node的实例 - 它将是Folder或File中的一个。

甚至更进一步,有些框架允许"实例化"接口(在技术上通过动态代理)。其中某些接口(例如预定义的基础接口)不允许作为参数提供。出于文档目的,在源代码中使用抽象修饰符来表示这些信息可能是有意义的。


0
问题:我们可以使用“abstract”关键字声明接口吗? 答案:是的,我们可以使用“abstract”关键字声明接口。但是,没有必要这样写。在Java中,所有接口默认都是抽象的。接口方法也是如此。
请访问以下链接: https://javaconceptoftheday.com/java-interview-questions-on-interfaces/ 自Java 8以来,接口可以具有静态方法。

0

接口的默认行为与您的示例基本相同。将其定义为抽象只是多余的。


0

我认为只有冗长、明确和与类语法和语义一致性...

你不必这样做,但如果代码的某个读者分心或不太熟悉Java,这可能会有所帮助。


这不正是相反的吗(正如这个线程所证明的)。 如果有人真的在写一个接口,他们必须知道接口是什么。在我看来,这更加令人困惑。 - Matt Wolfe
如果代码不仅是为自己而写,你应该考虑其他人的需求来编写。 - fortran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接