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

如何在受保护的java类上实现接口,java,class,interface,visibility,protected,Java,Class,Interface,Visibility,Protected,我想在包私有java类上实现一个接口,但我在实现这一点上遇到了一些困难。下面是一个例子 class Foo { String something(String str) { return ""str+"!"; } } public interface Bar { String something(String str); } 这里最好的方法是什么?我的最终目标是在Foo类上实现Bar接口。我希望能把Foo演成Bar:(Bar)Foo Ba

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

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




public interface Bar
{
    String something(String str);
}
这里最好的方法是什么?我的最终目标是在Foo类上实现Bar接口。我希望能把Foo演成Bar:(Bar)Foo

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


请告知。

Foo需要实施酒吧

受保护类Foo实现Bar

另外,我认为
Foo.something
需要公开才能实现
Bar.something

旁注:虽然这可能只是一个例子

返回“str+”

应该是:

返回str+“!”


如果Foo是包私有的,而您没有访问源的权限,只有类文件和/或包含Foo.class的jar,那么就没什么可做的了——默认包(其中没有指定包)和其他包中的类看不到包私有的东西。

Foo需要实现

受保护类Foo实现Bar

另外,我认为
Foo.something
需要公开才能实现
Bar.something

旁注:虽然这可能只是一个例子

返回“str+”

应该是:

返回str+“!”


如果Foo是包私有的,并且您没有访问源的权限,只有类文件和/或包含Foo.class的jar,那么就没什么可做的了——包私有的东西对于默认包中的类是不可见的(其中没有指定包)和其他包。

如果您对类没有控制权,但希望使它看起来像您拥有的API,则可以使用它来满足您的需要。提示:适配器模式

当您对一个类没有控制权,但希望使它看起来像您拥有的API时,您可以使用它来满足您的需要。提示:适配器模式

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

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

你不能。让包级别访问它以避免在外部看到该类的意义。但是,您可以做的事情(假定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?!
爸爸

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


我希望这有帮助。

你不能。让包级别访问它以避免在外部看到该类的意义。但是,您可以做的事情(假定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?!
爸爸

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


我希望这会有所帮助。

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

也许还有一种方法可以通过反射来改变相互作用,但我对此表示怀疑


Private的存在是有原因的。

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

也许还有一种方法可以通过反射来改变相互作用,但我对此表示怀疑



Private存在是有原因的。

Foo.something不是公共的,我没有访问权限。你知道Foo.something是否至少受到保护吗?根据你的例子,Foo.something是包可见的,我不知道我们能做多少。@andersra:你说“我没有访问权”是什么意思?Foo是包私有的,接口在另一个包中。我编辑了原始问题以反映这一点,抱歉,Foo.something不是公共的,我没有访问权限。您知道Foo.something是否至少受到保护吗?根据你的例子,Foo.something是包可见的,我不知道我们能做多少。@andersra:你说“我没有访问权”是什么意思?Foo是包私有的,接口在另一个包中。我编辑了原始问题以反映这一点,对不起。我的错误是,如果Foo是包私有的,这个解决方案仍然适用吗?这取决于。如果
Foo
在一个密封的JAR文件中,并且您没有源代码,那么您就没有运气(没有反射),因为您不能在其包之外引用
Foo
类型。情况可能并非如此,因此您仍然可以创建一个以
package foo
或任何包含
Foo
的包,并使用此方法。我的错误是,如果Foo是包私有的,此解决方案是否仍然适用?这取决于。如果
Foo
在一个密封的JAR文件中,并且您没有源代码,那么您就没有运气(没有反射),因为您不能在其包之外引用
Foo
类型。情况可能并非如此,因此您仍然可以创建一个以
package foo
或任何包含
Foo
的包,并使用此方法。这是我最初使用的方法,但我收到了错误:“Foo中的某个(字符串)无法在Bar中实现某个(字符串),试图分配较弱的访问权限;was public我也得到了它。然后刚刚添加:
public string something(字符串s){return super.something(s);}
您可以复制我提供的代码,并亲自查看。这就是为什么有必要使用返回
super.something(s)的公共版本覆盖
something(s)
。可能您拼错了覆盖的方法添加了
覆盖
注释。请参阅更新这是我最初使用的方法,但我收到错误:“Foo中的某个(字符串)无法在Bar中实现某个(字符串),尝试