Reputation: 2043
I am trying to build one page assembler using generic approach. Following is piece of code. In this code IEntity is marker interface for DB entities.
public abstract class PageHrefBuilder implements HrefBuilder<IEntity, PageLinks> {
@Override
public PageLinks buildLinks(IEntity entity) {
return null;
}
}
public interface HrefBuilder<E extends IEntity, L extends Links> {
public L buildLinks(E dto);
}
So we have one interface says can build links using IEntity type of class and return Links type of value. So I want to write some common code in abstract class and abstract class does not know what type entity it suppose to deal with. For example entity can UserEntity, OrderEntity and so on.
So my question is how in abstract class I can get the class instance to build links with using instanceof or if else approach.
Could someone help me on this.
Upvotes: 2
Views: 88
Reputation: 2395
This got a bit over-engineered but it works and all generics are proper. Hopefully it shows you how you can build your solution:
public class GenericsSample {
public abstract class Links {
String data;
public Links(String data) {
this.data = data;
}
}
public class UserLinks extends Links {
public UserLinks(String data) {
super(data);
}
}
public class PageLinks extends Links {
public PageLinks(String data) {
super(data);
}
}
public abstract class IEntity<L extends Links> {
public abstract L buildLinks();
}
public class UserEntity extends IEntity<UserLinks> {
@Override
public UserLinks buildLinks() {
return new UserLinks("From UserEntity");
}
}
public class PageEntity extends IEntity<PageLinks> {
@Override
public PageLinks buildLinks() {
return new PageLinks("From PageEntity");
}
}
public interface HrefBuilderInterface<E extends IEntity<L>, L extends Links> {
public L buildLinks(E dto);
}
public class HrefBuilder<E extends IEntity<L>, L extends Links> implements HrefBuilderInterface<E, L> {
@Override
public L buildLinks(E entity) {
return entity.buildLinks();
}
}
public static void main(String[] args) {
new GenericsSample().go();
}
private void go() {
System.out.println(new HrefBuilder<UserEntity, UserLinks>().buildLinks(new UserEntity()).data);
System.out.println(new HrefBuilder<PageEntity, PageLinks>().buildLinks(new PageEntity()).data);
}
}
Also note that thanks to this setup the following is not valid:
System.out.println(new HrefBuilder<PageEntity, PageLinks>().buildLinks(new UserEntity()).data);
Upvotes: 2
Reputation: 819
You can make your buildLinks method to take Class<T>
parameter instead of the object you have to pass.
so it will be
public L buildLinks(Class<E> dto);
then in your abstract class
@Override
public PageLinks buildLinks(Class<IEntity> dto) {
return dto.newInstance();
}
Hope this answer could help you.
Upvotes: 3
Reputation: 4515
You can declare abstract method
in abstract class to get new instance of Links
interface:
abstract class PageHrefBuilder<E extends IEntity, L extends Links> implements HrefBuilder<E, L> {
@Override
public L buildLinks(E dto) {
L links = newLinks();
// ...
return links;
}
protected abstract L newLinks();
}
and implement getting
new instance in realization.
Upvotes: 0