I'm working in some GWT application in which I have a hierarchy where I have an abstract presenter with some common functionality of derived classes. Something like:
public abstract class MyAbstractPresenter<T extends MyAbstractPresenter.CustomDisplay> extends Presenter<T>
{
public interface CustomDisplay extends View
{
//some methods
}
//I want to inject this element
#Inject
private CustomObject myObj;
public MyAbstractPresenter(T display)
{
super(display);
}
}
All the subclasses get injected properly. However, I want to be able to inject that particular field without having it to add it in the constructor of the subclasses. I tried to do field injection as you see , but it doesn't work as it is the subclasses the one that get injected.
Is there a proper way to achieve this Injection without letting the subclasses know about the existence of the field?
Apparently, as for the moment, there is no support for this type of behavior in GIN. A workaround would be to inject the required field in the concrete classes constructors even when they don't need it. Something like:
public abstract class MyAbstractPresenter<T extends MyAbstractPresenter.CustomDisplay> extends Presenter<T>
{
public interface CustomDisplay extends View
{
//some methods
}
//I wanted to inject this element
private final CustomObject myObj;
public MyAbstractPresenter(T display, CustomObject obj)
{
super(display);
myObj = obj;
}
}
Then in any class that extends this abstract implementation, I would have to pass it on construction.
public abstract class MyConcretePresenter extends MyAbstractPresenter<MyConcretePresenter.CustomDisplay>
{
public interface CustomDisplay extends MyAbstractPresenter.CustomDisplay
{
//some methods
}
#Inject //it would get injected here instead.
public MyConcretePresenter(CustomDisplay display, CustomObject obj)
{
super(display, obj);
}
}
Related
I am trying to do assisted injection in Guice.
Here are my implementations.
public interface Dao<T> {
T get(String id);
}
public class DaoImpl<T> implements Dao<T> {
private final Class<T> clazz;
DaoImpl(#Assisted final Class<T> clazz) {
this.clazz = clazz;
}
#Override
public T get() {
//Some impl code
return T;
}
}
Factory interface.
public interface DaoFactory {
<T> Dao<T> getDao(Class<T> clazz);
}
Guice module:
public class DaoModule extends AbstractModule {
#Override
protected void configure() {
install(new FactoryModuleBuilder()
.implement(new TypeLiteral<Dao<? extends Entity>>() {},
new TypeLiteral<DaoImpl<? extends Entity>>() {})
.build(DaoFactory.class));
}
}
I am getting error: "DaoFactory cannot be used as a key; It is not fully specified".
How should I be configuring the FactoryModuleBuilder?
My objective is to obtain a typed instance of Dao at runtime using DaoFactory
Assisted inject expects there to be a binding in place to select what you want to get returned to you - the parameters to your Factory interface must be just #Assisted-annotated parameters in the constructor of the desired implementation.
In this case, this means that in order for DaoFactory.getDao to take a T, then DaoImpl<T>'s constructor would need to take that T instance (annotated with #Assisted), and then that this would be enough somehow for that DaoImpl instance to be able to correctly build instances. Something like this, perhaps:
public class DaoImpl<T> implements Dao<T> {
public DaoImpl(#Assisted T instance) {
// Do something with the instance so this Dao is wired up right.
// perhaps with instanceof or instance.getClass()?
}
#Override
public T get() {
//Some impl code
return T;
}
}
That's all assisted inject knows how to do - it isn't magic that can create runtime lookups somehow, but this might be enough for you, depending on your use case. I'm not sure why DaoFactory.getDao would take an instance of T, and then Dao.get() would then return a T as well, but as that is part of the sample code in the question, I'm guessing you have this planned out already.
Update after the edit:
DaoFactory.getDao takes a T instance, but the constructor for DaoImpl is DaoImpl(#Assisted final Class<T> clazz) - assisted inject factories must take the same parameter that is expected to be passed in to the constructor. This is good news for your question - you can simply change your factory declaration slightly:
public interface DaoFactory {
<T> Dao<T> getDao(Class<T> obj);
}
Now you call getDao with something like MyEntity.class as the parameter, and will be given a Dao<MyEntity> instance, which was created by guice internally calling new DaoImpl(MyEntity.class).
If you want it specific to a some object, calling instance.getClass() and passing that in will have some generics effects you should understand, since getClass() actually returns a Class<?>, or at best a Class<? extends WhateverMyDeclaredTypeIs>. Consider the following:
class MyClass {}
class MySubclass extends MyClass{}
MyClass foo = new MySubclass();
factory.getDao(foo.getClass());// the generics will be a Dao<? extends MyClass>,
// not a Dao<MySubclass>, even though the DaoImpl.clazz holds an instance
// of MySubclass
Let's say that I have an interface, and all classes that implement that interface also extend a certain super class.
public class SuperClass {
public void someMethod() {...}
}
public interface MyInterface {
void someOtherMethod();
}
//many (but not all) sub classes do this
public class SubClass extends SuperClass implements MyInterface {
#Override
public void someOtherMethod() {...}
}
Then if I'm dealing with an object of type MyInterface and I don't know the specific sub class, I have to hold two references to the same object:
MyInterface someObject = ...;
SuperClass someObjectCopy = (SuperClass) someObject; //will never throw ClassCastException
someObjectCopy.someMethod();
someObject.someOtherMethod();
I tried making the interface extend the super class, but it's a compiler error:
public interface MyInterface extends SuperClass {} //compiler error
I also thought of combining the interface and the super class into an abstract class like so:
public abstract class NewSuperClass {
public void someMethod();
public abstract void someOtherMethod();
}
But then i can't have a sub class that doesn't want to implement someOtherMethod().
So is there a way to signify that every class that implements an interface also extends a certain class, or do I have no choice but to carry around two references to the same object?
I think that the only solution you have would be to have a reference to both, but this indicates that you have a design flaw somewhere. The reason I say is because you should think of an interface as something that your implementing classes will always need. For example, a Car and Airplane both need a Drive() interface. A design reconsideration is probably worth your time. However, if you still want to follow that path, you can do the following:
public class ClassA {
public void methodA(){};
}
public abstract class ClassB extends Class A{
public void methodB();
}
After you have the above setup, you can now reference an object that has the two methods by doing the following:
ClassB classB = new ClassB();
classB.methodA();
classB.methodB();
Now you don't actually have to actually use two pointers to the same object.
Is it possible to have something like that? I'm trying to force any class extending this one to implement an interface that extends BaseHomeListView
public abstract class BaseHomeFragment<T extends BaseHomeListView> extends BaseRecyclerViewFragment implements T
I'm trying to implement MVP pattern in Android for some fragments which only display lists.
So basically the view has to rendersList, that's why it is in the base interface, however I still want to allow each fragment to have add more methods as they need
public interface BaseHomeListView<T> extends LoadDataView, LoadMoreView<T> {
void renderList(Collection<T> items);
}
The only sensible thing you can do is the following:
public abstract class BaseHomeFragment<T>
extends BaseRecyclerViewFragment
implements BaseHomeListView<T>
And then if you have something like
public interface FancyHomeListView extends BaseHomeListView<Fancy> {
}
Then you can just have a fragment like
public class FancyHomeFragment
extends BaseHomeFragment<Fancy>
implements FancyHomeListView {
//...
}
Assuming you want to change the implementation of the interface's methods in every subclass, but not the arguments of such methods, or decouple the business code of the fragment's views, it would be more reasonable to add a generic instance of such interface as a member of your fragment class.
public abstract class BaseHomeFragment<T extends BaseHomeListView> extends BaseRecyclerViewFragment {
/*the class information can be used against a factory method to get an instance of the interface*/
private Class<T> myInterfaceClass;
protected T myInterfaceInstance;
public void setMyInterFaceInstance(T instance){
myInterfaceInstance = instance;
}
public BaseHomeFragment(Class<T> initializeClass){
myInterfaceClass = initializeClass;
myInterfaceInstance = interfaceFactory(myInterfaceClass);
}
//TODO: use the interface instance.
}
now, in every subclass, you'll need to add the interface subclass as an argument to super:
public class myAppHomeFragment extends BaseHomeFragment<AppHomeListView>{
public myAppHomeFragment(){
super(AppHomeListView.class);
setMyInterFaceInstance(new AppHomeListView{
//Method overloading
});
}
//TODO: Use the interface's new methods if necessary.
}
a little example of your factory method:
public static <T extends BaseHomeListView> T interfaceFactory(Class<T> aClass){
if(aClass.getSimpleName().equals("someclass")){
//TODO
return new someclass;
}
return null;
}
I've to create a simple self-made ActiveRecord class for my project.
Only stuck on the problem that I have a getModel() in my Player class, which is being extended by a ActiveRecord class.
When I want to use the getModel() method from my ActiveRecord class, I cant use it cause it's not the same type. I don't want to reference Player here, because I want to use multiple models.
Anyone has a solution?
Ok so I got something up:
abstract class ActiveRecord<T> {
private T model;
public T getModel() {
return this.model;
}
}
public class Player extends ActiveRecord<Player> {
}
public class Event extends ActiveRecord<Event> {
}
But when I try to output this.model in my ActiveRecord class, it return null.
What is wrong here?
Your method definition needs to do something like this
public Class<? extends ActiveRecord> getModel();
Meaning of this is that the return type is of class that extends ActiveRecord. When you do this to the child it would return Player.class as Player extends ActiveRecord.
A brief note if getModel return an object of that class then you should remove Class from the method function
public <? extends ActiveRecord> getModel();
So if I understand well you have a super class called ActiveRecord and a subclass Player, which has a method getModel.
If you want to use ActiveRecord as reference type then you need to have a getModel method in that class as well if you want to access that method. If you are never going to instantiate an ActiveRecord as such you can make it abstract and define the getModel method abstract. If you don't have any implementation logic in ActiveRecord you could make it an interface as well.
public abstract class ActiveRecord {
public abstract Model getModel();
}
public class Player extends ActiveRecord {
#Override
public Model getModel() {
...
}
}
You're making life way too hard for yourself. Java already does reflection for you.
class Parent {
// class content
}
class ChildA extends Parent {
// class content
}
class ChildB extends Parent {
// class content
}
Parent firstInstance = new ChildA();
Parent secondInstance = new ChildB();
Class typeOfFirst = firstInstance.getClass();
Class typeOfSecond = secondInstance.getClass();
As for your null pointer error, in Java (Unlike c++ for example) you have to explicitly initialise every variable with new. Just having private T model; doesn't create an instance of it.
I have a class component
abstract class Component{
private componentType m_type;
public Component(componentType type)
{
m_type = type;
}
}
and 2 subclasses
class AmplifierComponent extends Component{
public AmplifierComponent()
{
super(componentType.Amp);
System.out.print(this.m_type);
}
}
class AttenuatorComponent extends Component{
public AttenuatorComponent()
{
super(componentType.Att);
System.out.print(this.m_type);
}
}
my problems are:
1.i can't instantiate any kind of component because m_type isn't visible(what that means?)
2.i need to make an array of all the components the user has insert to the chain. i can't manage to create an array of Component class.
can someone help me with the design?
or with some workarounds?
Thanks in advance
I don't understand why you need the type member. This looks redundant. You can instead simply do:
abstract class Component{
}
class AttenuatorComponent extends Component{
public AttenuatorComponent() {
// calls the default super constructor
}
}
and rely on polymorphism for your classes to behave appropriately. Having a type member to identify a hierarchy type is unnecessary when you've declared the corresponding classes. If you do have a member variable that is required to be visible in subclasses but not by clients, then you can make it protected rather than private.
Component could be an interface if there's no functionality/data associated with it.
Your array declaration would look like
Component[] components = new Component[20];
components[0] = new AttenuatorComponent();
Polymorphism would mean that you can iterate through this array of components, calling appropriate methods declared on (but not necessarily implemented by) the Component, and the suitable subclass methods would be called.
Set m_type to protected to be able to see it from child classes.
abstract class Component {
private componentType m_type;
public Component(componentType type)
{
m_type = type;
}
public componentType getType()
{
return this.m_type;
}
}
class AmplifierComponent extends Component{
public AmplifierComponent()
{
super(componentType.Amp);
System.out.print(super.getType());
}
}
class AttenuatorComponent extends Component{
public AttenuatorComponent()
{
super(componentType.Att);
System.out.print(super.getType());
}
}
That way you can read m_type, but cannot change it.
You could also make the getType() command protected, so it is only reachable through the classes which inherit it.