2011-01-20 72 views
1

我正在寻求在包私有java类上实现接口,但我在实现上遇到了一些困难。下面是一个例子。如何在受保护的java类上实现接口

class Foo 
{ 
    String something(String str) 
    { 
     return ""str+"!"; 
    } 
} 




public interface Bar 
{ 
    String something(String str); 
} 

这里最好的办法是什么?我的最终目标是在Foo类上实现Bar接口。我希望能够将Foo当成Bar:(Bar)Foo

Bar接口和Foo类在单独的包中。有没有办法做到这一点?

请指教。

回答

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?! 

Da da!

诀窍是定义与父项相同的包中的子项,以便您可以创建它的公共版本。

我希望这会有所帮助。

1

美孚需要实施酒吧

protected class Foo implements Bar

另外,我觉得Foo.something需要是为了实现Bar.something

旁注公共:虽然这可能只是作为例如,

return ""str+"!";

应该是:

return str + "!";

如果foo是包私有的,你没有访问源,只是类文件和/或包含让Foo.class的罐子,有没有太多做 - 私有包的东西在默认包(没有指定包)和其他包的类中是不可见的。

+1

Foo.something不公开,我没有访问 – andersra 2011-01-20 01:59:50

+0

你知道吗如果Foo。有些东西至少受到保护?根据你的例子,Foo.something是包装可见的,我不知道我们能做多少。 – 2011-01-20 02:00:59

+0

@andersra:你说“我没有访问权限”是什么意思? – OscarRyz 2011-01-20 02:13:11

2

当你对某个班级没有控制权但你想让它看起来像一个你拥有的API时,那么你Adapt它适合你的需求。提示:适配器模式

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); 
    } 
} 
0

您可以尝试在BCEL或ASM中使用字节码注入并在运行时设置接口。虽然这很棘手。

也可能有一种方法来改变与反射的交互,但我怀疑它。

私人是有原因的。