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.
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.
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
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.
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);
}
}
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.
Related
import javax.security.auth.Subject;
abstract class Department extends Subject{
String name;
}
I have this piece of code. Sadly this throws the following error: The type Department cannot subclass the final class Subject
I was reading the documentation: https://docs.oracle.com/javase/7/docs/api/javax/security/auth/Subject.html but there is nothing much on how to use it(a specific use case).
Does anyone know how you can use Subject on an abstract Class (it has to be extended by an abstract class) ?
Edit:
Edit 2: Error Using Implements:
The type Subject cannot be a superinterface of Department; a superinterface must be an interface
Since Subject class is a final class you won't be able to extend it. That's the purpose of the final keyword. The only way I see is wrapping the class and its methods. You won't be able to use the wrapper where the final class is required, but you can implement any interfaces which are on the final class.
ex:
final class Foo {
public String getSomething() {
//
}
}
class Bar {
Foo foo;
public Bar() {
foo = new Foo();
}
public String getSomething() {
foo.getSomething();
}
public String doSomethingElse() {
//
}
}
Not sure it would be helpful in your scenario tho.
I want to extend final class in java to add a new method in inherited class. Which pattern should I use?
for example:
final class foo {
}
foo is a final class in java.
I want to extend this in built class to add extra functionality.
class bar extends foo {
dosomething(){
}
}
I can't extend final class. what should I do so that bar acts like foo with added functionality?
Is there a pattern to implement this functionality? So that it will execute all the functions of final class with added functionality
As you can't extend what you can do is to wrap the class and its methods. You won't be able to use the wrapper where the final class is required, but you can implement any interfaces which are on the final class
edit: Also see this discussion Equivalent to extending a final class in Java
final class Foo {
public String getSomething() {
//
}
}
class Bar {
Foo foo;
public Bar() {
foo = new Foo();
}
public String getSomething() {
foo.getSomething();
}
public String doSomethingElse() {
//
}
}
This is a simplified example of something I'm currently designing.
public class ExampleManager {
private Foo foo;
private ArrayList<Example> examples;
...
public ExampleManager() {
this.foo = new Foo();
this.examples = new ArrayList<Example>();
}
public void add(Example e) {
examples.add(e);
}
public void doSomethingWithExamples() {
for (int i = 0; i < examples.size(); i++) {
examples.get(i).doSomething();
}
}
...
}
public abstract class Example {
private Foo foo;
public Example(Foo foo) {
this.foo = foo;
}
...
}
In order to use the library, I have to extend the Example class and add examples to the ExampleManager, which should be the only class that modifies the Example objects.
So I have this Example1 class:
public class Example1 extends Example {
public Example1(Foo foo) {
super(foo);
}
...
}
and I currently initialize the manager like this:
ExampleManager manager = new ExampleManager();
Example1 example1 = new Example1(manager.getFoo());
manager.add(example1);
My Example needs the Foo object, but I'm wondering if I could get rid of the Foo argument in the Example1 constructor, so if someone uses the library, doesn't have to call manager.getFoo() in order to create an Example.
I'm thinking about the following solution, which will hide the Foo initialization, so the person who makes use of the library just have to implement the initialize(Foo) method, and the Foo would be initialized automatically when adding the example to the ExampleManager)
In ExampleManager: change the add(Example) method for:
public void add(Example e) {
e.initialize(foo);
examples.add(e);
}
In Example, initialize(Foo foo); would be an abstract method, so in Example1 I would have something like this:
#Override
public void initialize(Foo foo) {
this.foo = foo;
}
Is there any better way to do this?
It seems to me that you have some issues with your OO model in the first place if you need to hand objects around like you describe. - Or maybe your sample code does not reveal the real point of things.
Especially
ExampleManager [...] should be the only class that modifies the Foo objects
and
Example needs the Foo object
look somewhat 'special'.
Can you elaborate what the interactions are between the ExampleManager and the Foo instance, and between the Example and the Foo instance?
Ok, with regard to your comment, I propose the observer pattern, much like your initialize() approach:
public abstract class Example {
protected Foo callbackHandler;
public void setCallbackHandler( Foo handler ) {
this.callbackHandler = handler;
}
protected void doCallback( SomeType event ) {
if ( this.callbackHandler != null ) {
this.callbackHandler.doYourThing( event );
}
}
}
and have ExampleManager register itself or its Foo instance as the callback handler when an object is added to it. Non-abstract subclasses will then only need to call doCallback(...) whenever they want to communicate something and won't have to deal with any setup stuff for the callback.
I have a java program which uses arraylists - these arraylists store 'variables' where 'variables' is an abstract class.
Now, to save memory, I want to use a java library called HugeCollections-VanillaJava- however this library requires an interface to be defined.
How do I convert the abstract class into an interface? What rules/restrictions do I have to follow, to correctly perform the conversion?
Finally, is it possible for me to use my abstract class with minimal code changes, so that the library that requires an interface, also works correctly? Ideally I would like not to change the abstract class at all...Is this possible?
how do I convert an abstract class into an interface?
Make a copy of the abstract class source file.
Change "class" to "interface" in the initial declaration.
Change the name (optionally, depends on what you're doing).
Remove the bodies of any methods that are implemented by the class.
Remove the word "abstract" from the other ones.
Remove all private and protected members.
Remove all constructors.
Remove the keyword "public" from the public members.
If you had any code you removed (implemented methods, private or protected stuff), have your original abstract class implement your interface and leave that stuff there.
(Incomplete) Example:
Foo as an abstract class:
public abstact class Foo
{
private int bar;
public static final int SOME_CONSTANT = 42;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
Foo as an interface:
public interface Foo
{
int SOME_CONSTANT = 42;
void doSomething(String s);
}
In my case, as I did have some stuff the old Foo did, I'd probably have AbstractFoo or something:
public abstact class AbstractFoo implements Foo
{
private int bar;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
...so that an implementation could use it as a starting point if desired (although with that private bar in there, it doesn't make a lot of sense).
Pattern Adapter might help you.
Imagine, you're have to use SomeClass as TargetInterface
public abstract class SomeClass {
// some code here
public abstract void someMethod();
}
public interface TargetInterface {
public void someMethodBlaBla();
}
And they have different signatures of methods - someMethod() and someMethodBlaBla().
So you're might create such adapter class:
public class Adapter implements TargetInterface {
private SomeClass adaptee;
public Adapter( SomeClass adaptee ) {
this.adaptee = adaptee;
}
public void someMethodBlaBla() {
this.adaptee.someMethod();
}
//delegate all calls to adaptee
}
and somewhere in code you might use both - adapter and instance of abstract class, without interference on current code:
SomeClass abstractClassInstance = ... //get instance of your abstract class
TargetInterface targetInterfaceInstance = new Adapter( abstractClassInstance );
If abstract class does not define any concrete methods, you can even use regular expression for that. From:
public abstract class Abstract {
public abstract void method();
//...
}
to:
public interface Interface {
void method();
//...
}
public abstract modifiers are implicit for interfaces. If the abstract class does define some methods (not all methods are abstract) or have some fields this can't be done (at least easily).
I have a factory as below,
public final class Application {
private static IFoo foo;
public static IFoo getFoo(String bar)
{
// i need to inject bar to the constructor of Foo
// obvious i have to do something, not sure what
Injector injector = Guice.createInjector();
logger = injector.getInstance(Foo.class);
return logger;
}
}
This is the Foo definition:
class Foo
{
Foo(String bar)
{
}
}
OK. I m not sure how I can pass this parameter to Foo constructor with Guice?
Any ideas?
All the "Guice Constructor Parameter" answers seem to be incomplete in some way.
Here is a complete solution, including usage and a visual:
interface FooInterface {
String getFooName();
}
// Annotate the constructor and assisted parameters on the implementation class
class Foo implements FooInterface {
String bar;
#Inject
Foo(#Assisted String bar) {
this.bar = bar;
}
// return the final name
public String getFooName() {
return this.bar;
}
}
// Create a factory interface with a create() method that takes only the assisted parameters.
// FooFactory interface doesn't have an explicit implementation class (Guice Magic)
interface FooFactory {
Foo create(String bar);
}
// Bind that factory to a provider created by AssistedInject
class BinderModule implements Module {
public void configure(Binder binder) {
binder.install(new FactoryModuleBuilder()
.implement(FooInterface.class, Foo.class)
.build(FooFactory.class));
}
}
// Now use it:
class FooAction {
#Inject private FooFactory fooFactory;
public String doFoo() {
// Send bar details through the Factory, not the "injector"
Foo f = fooFactory.create("This foo is named bar. How lovely!");
return f.getFooName(); // "This foo is named bar. How lovely!"
}
}
Lots of helps here: https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/assistedinject/FactoryModuleBuilder.html
What you are probably looking for is to use a Guice factory. Particularly easy with the AssistedInject functionality, but they have a manual example at the top of the page. The short of it for the manual example is that you get the factory under non-static getFoo method that you pass whatever parameters to that you need and build the object from there.
This won't work directly if you have method interception in Foo, but it will work in many other cases.
To use AssistedInject, which to me has somewhat cleaner semantics and means less manual wiring, you'll need the guice-assistedinject extension in the classpath, then when creating Foo (well, FooImpl, we should be using interfaces):
#Inject
public FooImpl(#Assisted String bar)
{
this.baz = bar;
}
Then you create a FooFactory interface:
public interface FooFactory {
public Foo create(String bar);
}
Then in your guice module:
install(new FactoryModuleBuilder()
.implement(Foo.class, FooImpl.class)
.build(FooFactory.class));
You can check out the javadoc for FactoryModuleBuilder for examples with more complex factories.
I know that this is old thread but I just hit the issue myself today.
I only need two or maximum three different instances of 'Foo' and I really didn't want to write all the bolierplate code of Factory.
With a little googling I found this Stubbisms – Tony’s Weblog I would suggest this solution which is perfect if you know exactly what instances you need.
In Guice module:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic A");
}
});
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic B");
}
});
Or in java 8:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(() -> new FooImpl("first"));
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(() -> new FooImpl("second"));
And in constructor of your service where you need Foo instances:
#Inject
public MyService (
#Named("firstFoo") Foo firstFoo,
#Named("secondFoo") Foo secondFoo) {
}
And Foo in my case:
public class FooImpl implements Foo {
private String name;
public FooImpl(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
Hope it helps someone.
If this class is a factory, it should be a Guice-managed object, having a non static getFoo method, and the getFoo method would just use
new Foo(bar)
Not every class needs to be instantiated by Guice.
Also see AssistedInject, to avoid creating this factory yourself and let Guice create one for you.
Although this isn't a direct answer to what you're asking, hope it helps. I was trying to understand where the constructor parameters are being passed earlier. If they are custom classes, they should be bind-ed in the module.
Class CustomHandler {
private Config config;
#Inject
CustomHandler(Config config) {
this.config = config;
}
public void handle() {
// handle using config here
}
}
Binding:
class Module extends AbstractModule {
bind(Handler.class).to(CustomHandler.class);
bind(Config.class).to(CustomConfig.class);
}
Injection:
CustomHandler handler = injector.getInstance(CustomHandler.class);
handler.handle();