我希望在一个包私有java类上实现一个接口,但是我在实现这个方面遇到了一些困难。以下是一个例子。
class Foo
{
String something(String str)
{
return ""str+"!";
}
}
public interface Bar
{
String something(String str);
}
这里最好的方法是什么?我的最终目标是在Foo类上实现Bar接口。我希望能够把Foo当作Bar:(Bar)Foo
Bar接口和Foo类位于不同的包中。有没有办法做到这一点?
请告知。
答案 0 :(得分:2)
如果您对某个课程没有控制权但想让它看起来像您拥有的API,那么您Adapt就可以满足您的需求。提示:适配器模式
答案 1 :(得分:2)
你做不到。让包级别访问它以准确避免在外面看到该类。然而,你可以做什么(授予Foo不是最终的)是这样的:
C:\>type *.java
//Foo.java
package foo;
class Foo {
String something( String s ) {
return s + "!";
}
}
//Bar.java
package bar;
public interface Bar {
public String something( String s );
}
//Baz.java
package foo;
import bar.Bar;
public class Baz extends Foo implements Bar {
// make sure you're overriding
@Override
public String something ( String s ) {
return super.something( s );
}
}
//Use it: Main.java
package bar;
import foo.Baz;
class Main {
public static void main( String ... args ) {
Bar bar = new Baz();
System.out.println( bar.something("like this?"));
}
}
C:\>java bar.Main
like this?!
诀窍是将子项定义在与父项相同的包中,以便您可以创建它的公共版本。
我希望这会有所帮助。
答案 2 :(得分:1)
Foo需要实施 Bar
protected class Foo implements Bar
此外,我认为Foo.something
需要公开才能实施Bar.something
旁注:虽然它可能就是一个例子,
return ""str+"!";
应该是:
return str + "!";
如果Foo是包私有的,并且你没有访问源,只有类文件和/或包含Foo.class的jar,那就没什么可做的 - 包私有的东西对于类是不可见的默认包(没有指定包)和其他包。
答案 3 :(得分:1)
如果您无权访问Foo
的源代码,则需要使用继承或合成。
// By logically including your code in the package containing Foo,
// you can now access it. If Foo belongs to the default package, sorry.
// This also doesn't work if the package is sealed.
package where.foo.resides;
public interface Bar {
String something(String s);
}
// Inheritance
public class FooBar extends Foo implements Bar {
public String something(String s) {
return super.something(s);
}
}
// Composition
public class ComposedFooBar implements Bar {
private final Foo delegate;
public ComposedFooBar(Foo delegate) {
this.delegate = delegate;
}
public String something(String s) {
return delegate.something(s);
}
}
答案 4 :(得分:0)
您可以尝试使用BCEL或ASM的字节码注入,并在运行时设置接口。但这很棘手。
可能还有一种方法可以改变与反射的相互作用,但我对此表示怀疑。
私人是有原因的。