Java中的接口:无法使实现的方法受保护或私有
我知道接口必须是公共的。然而,我不想这样 我希望实现的方法只能从它们自己的包中访问,因此我希望实现的方法受到保护 问题是我无法保护接口或实现的方法 什么是工作环境?是否存在与此问题相关的设计模式Java中的接口:无法使实现的方法受保护或私有,java,interface,access-specifier,Java,Interface,Access Specifier,我知道接口必须是公共的。然而,我不想这样 我希望实现的方法只能从它们自己的包中访问,因此我希望实现的方法受到保护 问题是我无法保护接口或实现的方法 什么是工作环境?是否存在与此问题相关的设计模式 根据Java指南,抽象类也不能完成这项工作。您可以使用封装而不是继承 也就是说,创建你的类(它不会继承任何东西),并在其中拥有你想要扩展的对象的实例 然后你可以只暴露你想要的 这种方法的明显缺点是,必须显式地传递所有要公开的方法。而且它不会是一个子类…read 公共访问说明符表示该接口可由任何包中的任何
根据Java指南,抽象类也不能完成这项工作。您可以使用封装而不是继承 也就是说,创建你的类(它不会继承任何东西),并在其中拥有你想要扩展的对象的实例 然后你可以只暴露你想要的 这种方法的明显缺点是,必须显式地传递所有要公开的方法。而且它不会是一个子类…read 公共访问说明符表示该接口可由任何包中的任何类使用。如果不指定该接口为公共接口,则只有在与该接口相同的包中定义的类才能访问该接口。
这就是您想要的吗?您的类可以使用包保护并仍然实现一个接口:
class Foo implements Runnable
{
public void run()
{
}
}
public interface Iface {
public void doSomething();
}
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
如果您希望保护/打包某些方法,而不希望保护/打包其他方法,那么听起来您的类有不止一个职责,应该划分为多个
阅读此回复和其他回复的评论后进行编辑:
如果您认为方法的可见性会影响调用该方法的能力,请三思。如果不走极端,就无法阻止某人使用反射来标识类的方法并调用它们。然而,这不是问题:除非有人试图破解您的代码,否则他们不会调用随机方法
相反,将私有/受保护方法视为定义子类的契约,并使用接口定义与外部世界的契约
哦,对于那个决定我的例子应该使用K&R支撑的人:如果服务条款中有规定,当然可以。否则,你就找不到更好的方法来利用你的时间了吗?下面是使用抽象类的方法 唯一不方便的是,它使您成为“子类” 根据java指南,您应该在大多数情况下遵循该建议,但我认为在这种情况下它是可以的
public abstract class Ab {
protected abstract void method();
abstract void otherMethod();
public static void main( String [] args ) {
Ab a = new AbImpl();
a.method();
a.otherMethod();
}
}
class AbImpl extends Ab {
protected void method(){
System.out.println( "method invoked from: " + this.getClass().getName() );
}
void otherMethod(){
System.out.println("This time \"default\" access from: " + this.getClass().getName() );
}
}
我只需要创建一个抽象类。这没有什么害处。当我遇到这个问题时,我使用一个包可访问的内部或嵌套类来实现接口,将实现的方法从公共类中推出 通常这是因为我有一个带有特定公共API的类,它必须实现其他东西才能完成它的工作(通常是因为其他东西是伪装成接口的回调)——这在类似Comparable的情况下经常发生。我不希望公共API受到(强制公共)接口实现的污染 希望这有帮助 另外,如果您确实希望只由包访问方法,那么您不需要受保护的范围说明符,而是需要默认(省略)的范围说明符。当然,使用protected将允许子类查看方法
顺便说一句,我认为接口方法被推断为公共的原因是,只有一个接口是由同一个包中的类实现的,这在很大程度上是一个例外;它们通常被另一个包中的某些东西调用,这意味着它们需要公开。这个问题基于一个错误的陈述: 我知道接口必须是公共的 不是真的,您可以使用默认访问修饰符创建接口 问题是我无法保护接口或实现的方法 这是:
C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;
interface Inter {
public void face();
}
a\Face.java
package a;
class Face implements Inter {
public void face() {
System.out.println( "face" );
}
}
C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java
package b;
import a.Inter;
import a.Face;
public class Test {
public static void main( String [] args ) {
Inter inter = new Face();
inter.face();
}
}
C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
^
b\Test.java:7: cannot find symbol
symbol : class Inter
location: class b.Test
Inter inter = new Face();
^
b\Test.java:7: cannot find symbol
symbol : class Face
location: class b.Test
Inter inter = new Face();
^
4 errors
C:\oreyes\cosas\java\interfaces>
因此,要实现您想要的,就要防止在包之外使用接口和类。对于一个接口,您要定义可由各种实现类公开的方法。 拥有一个带有受保护方法的接口就不能达到这个目的
我猜你的问题可以通过重新设计你的类层次来解决。 < P>这里有另一个解决方案,灵感来自C++ piml习惯用法。< /P> 如果希望实现接口,但不希望该实现是公共的,则可以创建实现该接口的匿名内部类的组合对象 这里有一个例子。假设您有这个接口:
class Foo implements Runnable
{
public void run()
{
}
}
public interface Iface {
public void doSomething();
}
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
创建一个Iface
类型的对象,并将实现放在其中:
public class IfaceUser {
private int someValue;
// Here's our implementor
private Iface impl = new Iface() {
public void doSomething() {
someValue++;
}
};
}
无论何时需要调用
doSomething()
,您都可以在组合的impl
对象上调用它。我只是在尝试构建一个受保护的方法时遇到了这个问题,目的是只在测试用例中使用它。我想删除填充到DB表中的测试数据。不管怎么说,我的灵感来自于他的。不幸的是,它没有起作用。我确实找到了一种使用受保护的内部类使其工作的方法
界面:
class Foo implements Runnable
{
public void run()
{
}
}
public interface Iface {
public void doSomething();
}
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
然后在公共类中定义为受保护的内部类:
package foo;
public class MyFoo implements SomePublicFoo {
// public stuff
protected class ProtectedFoo implements SomeProtectedFoo {
public int doSomeFoo() { ... }
}
protected ProtectedFoo pFoo;
protected ProtectedFoo gimmeFoo() {
return new ProtectedFoo();
}
}
然后,您只能从同一包中的其他类访问受保护的方法,因为我的测试代码如下所示:
package foo;
public class FooTest {
MyFoo myFoo = new MyFoo();
void doProtectedFoo() {
myFoo.pFoo = myFoo.gimmeFoo();
myFoo.pFoo.doSomeFoo();
}
}
原来的海报有点晚了,但是嘿,我刚找到它D解决这个问题的一种方法是(根据具体情况)创建一个匿名内部类,该类实现了受
保护的或私有的作用域的接口。例如:
public class Foo {
interface Callback {
void hiddenMethod();
}
public Foo(Callback callback) {
}
}
然后在Foo
的用户中:
public class Bar {
private Foo.Callback callback = new Foo.Callback() {
@Override public void hiddenMethod() { ... }
};
private Foo foo = new Foo(callback);
}
这样可以避免出现以下情况:
public class Bar implements Foo.Callback {
private Foo foo = new Foo(this);
// uh-oh! the method is public!
@Override public void hiddenMethod() { ... }
}
我想你现在可以在Java9版本中使用它了。从Java 9的openJdk注释中
对接口中私有方法的支持也在考虑之中
作为添加对的支持的一部分,包含在JavaSE8中