【问题标题】:How to only allow implementations of an interface in the same package如何只允许在同一个包中实现接口
【发布时间】:2012-10-16 22:53:48
【问题描述】:

我有一个包裹 P

  • public interface I
  • public class S1 extends Foo implements I
  • public class S2 extends Bar implements I

现在我想禁止在P 之外实现I,但I 应该是公开的,因为我将它用于public method(I parameter)

如何做到这一点?

是否有一些“包装最终模式”?

你有过这样的情况吗?


详情:

我知道使用抽象类的可能性只有包私有构造函数而不是接口I,但是S1S2 扩展了不同的类,所以我需要多重继承(因为模拟多重继承(参见例如 Effective Java item 18)在这里不起作用)。

【问题讨论】:

  • 如果你不需要包外的接口,你可以只设置接口包范围:接口I,而不是公共接口I。
  • @karakuricoder:我需要包外的接口(请参阅我对 Ian Armit 的回答的评论)。

标签: java interface package visibility multiple-inheritance


【解决方案1】:

做不到。如果你的接口是public,任何人都可以实现它。您的两个实现是否可以扩展一个抽象类并封装它们当前正在扩展的那些?

更好的问题是您真的需要执行此规则吗?接口的重点是您应该能够接受和实现该接口。如果您确实需要,您可以在使用接口时进行验证,方法是检查实例的类是否是您允许的两个类之一。

【讨论】:

  • 其他语言确实有类似的设施。例如,C# 具有访问修饰符 internal,它使接口仅在 程序集 中可用。
  • 正如其他人指出的那样,默认范围是包私有的,但由于 OP 将接口列为 public 我假设需要从包外部引用该接口(正如 OP 所确认的那样评论)
  • @John:答案+1,尽管我希望有更好的解决方案。目前我正在做某事。就像您建议的那样:使用this.getClass().getPackage()!= paraeter.getClass().getPackage()) 动态检查,因此我可以在包内扩展I 而无需更新检查。
  • 是的,我感觉到你,但我认为你被困住了。
【解决方案2】:

如果你做了接口声明

interface I

它应该使它只能从包和类中访问

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

【讨论】:

  • 那时我无法拥有public method(I parameter)(因此为-1)。
【解决方案3】:

您也可以尝试以下尝试:

使用虚拟包私有接口并在您的公共接口中创建一个返回它的方法。像这样:

public interface I {
  Dummy getDummy(); // this can only be used and implemented inside of the 
                    // current package, because Dummy is package private
  String methodToUseOutsideOfPackage();
}

interface Dummy {}

因此,只有当前包中的类才能实现接口I。来自外部的所有类将永远无法实现方法Dummy getDummy()。同时,包外部的类将能够使用接口I 的所有其他方法,这些方法在其签名中没有Dummy 接口。

这个解决方案并不漂亮,因为你的界面I中有一个无用的方法,但你应该能够实现你想要的。

【讨论】:

  • 我想指出的是,如果某个类 A 实现了接口 I,那么 A 可以被 I 包之外的某个类 B 扩展。 (然后 B 是 I 的包之外的 I 的实现)。为防止这种情况,任何实现 I 的类(例如 A)都应声明为 final 或具有具有包可见性的构造函数。
猜你喜欢
  • 1970-01-01
  • 2011-05-16
  • 2014-05-23
  • 2014-05-09
  • 2015-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
相关资源
最近更新 更多