Why should we declare interface methods as public?
当我实现一个interface方法时,我被迫使它成为public方法。
我们可能需要使用default或protected。
有人能解释这个限制背后的原因吗?
- 如果需要受保护的私有成员或静态方法和非静态字段,可以使用abstract class。
接口是用来定义一个类型的公共API的,并且仅此而已,而不是它的实现。因此,您在接口中定义的任何方法(或静态成员)都是通过定义public定义的。
由于接口不能包含任何具体的实现,因此无法从内部调用任何成员方法。声明这样的方法,但将调用留给子类或完全不相关的客户机,这意味着您的类型定义是不完整和脆弱的。这就是为什么如果需要定义受保护或包访问成员,可以在抽象类(也可能包含实现)中这样做。
- 我认为这个答案是正确的,但它基本上是一种迂回的方式,说:"因为这就是Java人想要的。"你可以想出完全合理的理由来保护方法(包私有可能有点难以证明)。但是您当然不能拥有私有方法,因为这些方法从未被继承。我的猜测是,他们认为与其说"这是一部分可见性,这就是为什么这不是那个",不如说"这是你得到的可见性"。
- YSavIT,我试着思考为什么Java的人想要这样的事情。上面提到的一条信息是,他们增加了语言的接口,特别是因为他们想禁止多重继承,以及它在C++中提出的所有问题。
- @yshavit,会对任何"拥有保护方法的完全合理的论据"感兴趣,尽管:—)
- +1用于说明接口和抽象类之间的概念差异。
- 从技术上讲,这些方法都是公共的——如果您有对象引用,那么您总是可以获得对接口的引用。
- 这只是语言依赖。在C中,接口总是公开的。
- @P&233;Tert&246;R&246;K就在我的头顶上,我可以想象一个接口,它可以收集和报告某种类型的信息,但是它也有回调方法,在调用者一侧具有特定的承诺(例如,它们都在特定的线程上被调用)。如果您可以标记那些受保护的对象,以便只有定义接口的包才能访问它们(当然还有类本身),那就太好了。或者,您可能不希望人们能够直接使用getFoo(),而只希望通过一种方法(在包的某个地方定义)在返回之前将其包装在某个Bar中。等。
- @通过使用两个独立的接口(其中一个是包私有的)可以很容易地解决所有这些问题。
- @即使您这样做了,实现接口的具体类也必须将这些方法公开。所以这些方法仍然是公共API的一部分,只是没有组织成包私有接口的一部分…几乎是两个世界中最糟糕的,因为您必须发布这个概念上隐藏的方法,而不是它定义的上下文。
- @只有为具体的类而不是接口编程时,才能执行yshavit。否则,将publicInterface实例发布到某个客户机(可能在另一个包中),将packageprivateInterface实例发布到另一个客户机(在同一个包中)。没有人关心这些是否是同一个物理物体。
也许这会提供一些答案。
据我所知,您使用interfaces允许来自代码外部的人员与您的代码交互。为此,您需要定义方法public。
如果您希望强制某人重写一组给定的私有方法,那么您可能希望用一系列抽象保护方法声明一个抽象类。
- "抽象私有方法"…你是说"抽象保护方法"?
- @npinti用最简单的话来说很好!
- @是的,你是对的。修好了,谢谢:)
- 或抽象默认(包)范围方法
- 然而,JoshuaBloch强烈鼓励我们使用接口作为类型,并使用这些类型来引用对象。这是一个不错的主意,但它发展了两种概念化接口的方法:作为一种使用用户定义的类型的机制,以一种不干扰单一继承的方式使用;以及作为一个API契约。既然我们有这两个接口,我同意如果我们不需要公开接口方法来保持那些不希望导出封装的UDT,那就太好了。
接口是一个约定,实现它的类将在接口中具有方法。该接口用于向程序的其余部分显示该类具有方法,并且可以调用这些方法。
- 是的,但是接口也是类型。有时,程序员希望使用他们创建的类型,而不将它们作为API的一部分导出。这就是强制接口方法公开的地方,这很烦人。
编辑:此答案适用于C接口实现。在这种情况下,Java语法类似于语法分析器需要在接口中提到的公共关键字,这在C语言中是隐式的。
接口方法在C中是隐式公共的,因为接口是一个约定,用于其他类。此外,在实现接口时,必须将这些方法声明为公共方法,而不是静态方法。
1 2 3 4 5
| interface IStorable
{
void Read( );
void Write(object obj);
} |
注意,Read( )和Write( )的IStorable方法声明不包括访问修饰符(public和protected)。实际上,提供访问修饰符会生成编译错误。
1 2 3 4 5 6 7 8 9 10 11
| class Document : IStorable
{
public void Read ( )
{
//
}
public void Write (object obj )
{
//
}
} |
只需将接口视为要作为public实现的契约。
- 在爪哇中,实际上需要指定EDCOX1的2个关键字。
- @唉,我的错,也许我没有看到问题的相关标签。我在C中讨论过这个案子,我会在编辑中提到。
如果我们将接口方法标记为私有,则实现类将不会查看方法并不能覆盖它。
如果我们将接口方法标记为受保护的实现类除非方法与接口。
如果我们标记一个没有任何访问修饰符的接口方法,实现类除非在同一个方法中,否则将看不到该方法包作为接口