如何在受保护的java类上实现接口

发布于 2024-10-13 02:17:42 字数 350 浏览 5 评论 0原文

我想在包私有 java 类上实现一个接口,但实现这一点遇到一些困难。下面是一个例子。

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




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

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

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

请指教。

I was looking to implement an interface on a package-private java class, but I am having some difficulty achieving this. Below is an example.

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




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

What is the best approach here? My end goal is to implement the Bar interface on the Foo class. I am hoping to be able to cast Foo as Bar: (Bar)Foo

The Bar interface and the Foo class are in separate packages. Is there a way to do this?

Please advise.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

司马昭之心 2024-10-20 02:17:42

你不能。让包级别访问它的目的是为了精确避免在外部看到该类。然而你可以做什么(假设 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!

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

我希望这有帮助。

You can't. The point of having the package level access it to precisely avoid seeing that class outside. What you can do however ( granted Foo is not final ) something like this:

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!

The trick is to define the child in the same package as the parent so you can create a public version of it.

I hope this helps.

眉黛浅 2024-10-20 02:17:42

当您无法控制某个类,但希望使其看起来像您拥有的 API 时,您可以 调整以满足您的需求。提示:适配器模式

When you doesn't have control on a class but you want to make it look like an API that you have, then you Adapt it to fit your needs. Hint: Adapter Pattern

初心 2024-10-20 02:17:42

Foo 需要实现 Bar

受保护的类 Foo 实现 Bar

另外,我认为 Foo.something 需要public为了实现 Bar.something

旁注:虽然它可能只是作为示例,但

return ""str+"!";

应该是:

return str + " !";

如果 Foo 是包私有的,并且您无权访问源代码,只能访问类文件和/或包含 Foo.class 的 jar,则无需做太多事情 - 包私有的东西是对于默认包(没有指定包)和其他包中的类不可见。

Foo needs to implement Bar

protected class Foo implements Bar

Also, I think Foo.something needs to be public in order to implement Bar.something

Side Note: While it was probably just as an example,

return ""str+"!";

should be:

return str + "!";

If Foo is package private, and you don't have access to the source, just the classfiles and/or the jar containing Foo.class, there's not much to do -- something that is package private is invisible to classes in the default package (where there is no package specified) and other packages.

┾廆蒐ゝ 2024-10-20 02:17:42

如果您无法访问 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);
    }
}

You'll need to use inheritance or composition if you don't have access to the source code of 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);
    }
}
不离久伴 2024-10-20 02:17:42

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

可能还有一种方法可以改变与反射的交互,但我对此表示怀疑。

私人的存在是有原因的。

You can try using bytecode injection with BCEL or ASM and setting the interface at runtime. It's tricky, though.

There might also be a way to change interaces with reflection, but I doubt it.

Private is there for a reason.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文