I've got some code like this:
public abstract class Foo {
public static Foo getFoo() {
return new FooImpl();
}
abstract void DoFoo();
private class FooImpl extends Foo {
public FooImpl() { }
#Override
void DoFoo() { }
}
}
But Eclipse is telling me No enclosing instance of type Foo is accessible. So how can I get this to work?
I attempted to make it as simple as possible to see if it would compile:
public abstract class Foo {
public static Foo getFoo() {
return new FooImpl();
}
private static class FooImpl extends Foo {
public FooImpl() { }
}
}
And I still get the same error. What am I missing?
FIXED! I changed the line return new FooImpl(); to return new Foo.FooImpl();
Excellent explanation here -- in brief, you need to make class FooImpl static, so it's only tied to the outer class, not to a specific instance of the outer class (which you don't have). The getFoo method also looks like it should be static, btw -- otherwise, what instance of Foo were you planning on calling it on?
How do you intend people to call getFoo()?
Unless you're doing something completely funky and radical, you'll need to make it static.
Make the FooImpl class static and it will work.
Related
I want a method in a derived class to override a virtual method in a CONCRETE base class AND return something (i.e. not void) like this:
public class HelloWorldApp
{
public static void main(String args[])
{
Bar bar = new Bar();
bar.go();
}
}
public class Foo
{
public void go()
{
System.out.print(this.test().toString());
}
protected Integer test()
{
return 1;
}
}
public class Bar extends Foo
{
#Override
protected Integer test()
{
return 2;
}
}
Is there any way of doing this without the redundant 'return 1;' in Foo.test() which will never get run. It works fine obviously but it just seems like I'm doing something badly wrong.
This answer was created before the question was updated to state that the base class must be concrete.
If you expect Foo's test method never to be run, then enforce it by making the Foo class abstract, with test being abstract.
public abstract class Foo {
public void go() {
System.out.print(this.test().toString());
}
abstract protected Integer test();
}
If you cannot make Foo.test() abstract for some reason you didn't show in your example (for example because Foo extends a concrete class) and you are sure it will never be called, throwing a runtime exception may be preferable if there is no reasonable default value:
protected Integer test()
{
throw new UnsupportedOperationException("Calling test on Foo is not supported");
}
There are examples for this in the Java core APIs, see for example UnsupportedOperationException - this one has a slightly different meaning though, it is used for optional methods that some implementations of certain collection-types implement and some don't.
Toy example:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(new Provider<Bar>() {
#Override public Bar get() {
return foo.getBar();
}
});
}
}
This lets me lazily invoke the .getBar() method of a user-provided Foo instance stored in a field of MyModule. However now the provider has its own dependencies - hence I need to define a non-anonymous class I specify an #Inject constructor on. Something like:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(BarProvider.class);
}
BarProvider implements Provider<Bar> {
private Baz baz;
#Inject BarProvider(Baz baz) {
this.baz = baz;
}
#Override public Bar get() {
return foo.getBar(baz);
}
}
}
Perfect! Except Guice doesn't like this...
Exception in thread "main" com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Injecting into inner classes is not supported. Please use a 'static' class (top-level or nested) instead of com.example.MyModule$BarProvider.
So, I'm in a bind. I need to access both a field on the module and an injected type from a Provider class at the same time. Is there any way to do this?
Note: this toy example excludes some of the actual complexity - in particular the bind() statement is more involved, which is why I can't simply define an #Provides method.
In part, injecting into an inner class is impossible because Guice can't reflectively create an inner instance without an outer parent instance (the equivalent of the arcane outerInstance.new InnerInstance() syntax).
Some options:
Make Foo injectable through your graph, possibly hidden in a PrivateModule so it's not exposed to your entire graph (if that's important to you).
Use an anonymous inner Provider (or an extracted equivalent), and get a Provider<Baz> from AbstractModule's getProvider(Class<T>) method. You'll get an exception if you try to call that before the Injector is created, but for creating a Provider the way you're doing, that's probably not a problem.
Post your bind outside of a toy problem, to see whether #Provides is possible with some cleverness.
Related: Accessing Guice injector in its Module?
I realize I was getting hung up on having Guice construct my Provider for me, which I don't actually need to do. Despite the example in Guice's documentation passing in a DatabaseTransactionLogProvider.class a better parallel to the first snippet would be to construct an instance of my Provider manually, and pass in both the Foo instance and a Provider<Baz> instance (provided by the module).
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(new BarProvider(foo, getProvider(Baz.class));
}
static BarProvider implements Provider<Bar> {
private final Foo foo;
private final Provider<Baz> bazProvider;
BarProvider(Foo foo, Provider<Baz> bazProvider) {
this.foo = foo;
this.bazProvider = bazProvider;
}
#Override public Bar get() {
return foo.getBar(bazProvider.get());
}
}
}
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).
public class Cls1{
public foo(){
doX();
}
}
public class Cls2{
public foo(){
doY();
}
}
Cls2 cls = new Cls2();
cls.foo();
Is there a way to do inheritance in java that java runs both doX and doY when the user calls the function with foo?
Yes, but you have to do it explicitly:
public class Cls1{
public foo{
doX();
}
}
public class Cls2 extends Cls1 {
public foo{
super.foo();
doY();
}
}
Note: I assume you meant for Cls2 to extend Cls1, otherwise your question makes no sense at all.
public class Cls1 {
public foo{
doX();
}
}
public class Cls2 extends Cls1 {
public foo{
super.foo();
doY();
}
}
Cls2 cls = new Cls2();
cls.foo();
private class Cls2 extends Cls1 {
public void foo {
doY();
super.foo();
}
}
first of all, I assume you mean:
public class Cls2 extends Cls1{
and yes, there is:
public (something?) foo(){
super.foo();
doY();
}
The super keyword allows access to the super-class's methods. If it's simply called on its own:
super(...);
then it calls the super-class's constructor.
Assuming that Cls1 and Cls2 inherit from each other in some way, you can use the keyword super to call the superclass's implementation of a method if you want to, for instance, in the derived class perform both functions.
If doX() and doY() were statically imported (which, as they were not defined in Cls1 or in Cls2 is the only way I can think of for this program to compile), then you can make a new class with a method foo that calls doX and doY without using inheritance. Those methods named foo would have nothing to do with each other, however.