3

Trying to implement a generic and inheritance classes in a Java Project. For that reason I created the "Base" classes and Interfaces that will inheritance all the specific classes and interfaces.

I mean, I have a Base Interface

public interface BaseServices<T> {
    public boolean validate(T item, int id) throws Exception;
}

And a Base Implementation for that Interface

public class BaseServicesImpl implements BaseServices<BaseBO> {

@Autowired
BaseDao dao;
CategoryBO bo;

public BaseServicesImpl()
{
    this.bo = new CategoryBO();
}

    @Override
       public boolean validate(BaseBO item, int id) throws Exception {
       return dao.validate("name",item.toString(), id);
    } 
}

Where BaseBO is the business object that ALL the other objects will extend.

And then, for an specific object, I will have a particular Interface which extends the Base one.

public interface CategoryServices extends BaseServices {
    }

And its implementation:

public class CategoryServicesImpl extends BaseServicesImpl implements CategoryServices<CategoryBO> {

    @Autowired
    CategoryDao categoryDao;

    public CategoryServicesImpl()
    {
        this.dao = categoryDao;
    }

    @Override
    public boolean validate(CategoryBO item, int id) throws Exception {
            return dao.validate("name",item.getName(), id);
    }
}

Where some object can implement the generic "Validate" method (which validates just the name) or extend it to what the class requiredpublic class CategoryServicesImpl extends BaseServicesImpl implements CategoryServices.

How can I make this work? Is it possible? I'm trying to do the most I can to reuse my code. Let me know if there is another way.

EDITED: What I'm trying to do, is to have a base class with all the common method for all the classes, let say, the basic for create, edit, delete, get, getAll, etc. And then in each class I also can have and override for those method because in some classes they will be different, but in most, they will just do the same so it will call the generic ones that were defined in Base class.

10
  • "How can I make this work?" What exactly are you trying to make work? Commented Feb 2, 2016 at 3:02
  • 1
    This is probably abuse of inheritance and will give you headaches down the road. My advice: remove duplication by refactoring, rather than a big up front class hierarchy. Commented Feb 2, 2016 at 3:04
  • tl;dr, but at first glance it seems that at least BaseDao, and possibly CategoryDao, should also be typed, probably with the same type as the impl Commented Feb 2, 2016 at 3:07
  • You say that CategoryServicesImpl extends BaseServicesImpl, but why? I see no benefit from it. Commented Feb 2, 2016 at 11:53
  • @AustinD I added some extra information about what I want to do. Commented Feb 2, 2016 at 11:54

2 Answers 2

5

You can easily achieve what you want, just with a couple of changes:

public interface BaseServices<T extends BaseBO> {

    boolean validate(T item, int id) throws Exception;
}

public interface CategoryServices 
    extends BaseServices<CategoryBO> {
}

public class BaseServicesImpl<T extends BaseBO> 
    implements BaseServices<T> {

    @Override
    public boolean validate(T item, int id) throws Exception {
        return true;
    }
}

public class CategoryServicesImpl 
    extends BaseServicesImpl<CategoryBO> 
    implements CategoryServices {

    @Override
    public boolean validate(CategoryBO item, int id) throws Exception {
        return true;
    }
}

The key is to let your generic T type be a descendant of BaseBO, and then adjust your BaseServicesImpl class to also be generic.

Sign up to request clarification or add additional context in comments.

1 Comment

I marking this answers are correct because it works! but at the end I mix some of this answer with @munk 's comment to simplify some things
1

Caveat see my comment on good design. Simplicity is the key to good software. Over-engineering is the road to madness.

If you have an interface and you need to share to the implementation of some methods between classes that implement that interface, you can use an Abstract Base Class to implement the methods you need to share.

public interface Service<T> { 
    //note, interfaces are implictly public
    boolean validate(T item, int id) throws Exception;
    void foo();
    void bar();
}

public abstract class BaseService<T> {
    boolean validate(T item, int id) throws Exception {
        return false; // a default implementation
    }
    public abstract void foo();
    public abstract void bar();
}

public class FooService<T> extends BaseService<T>{
    public void foo() {
        println("foo"); 
    }
    public void bar() {
        println("bar"); 
    }
}

With Java 8, it's also possible to provide default implementations in an interface.

public interface Service<T> { 
    boolean validate(T item, int id) throws Exception;
    void foo();
    void bar();
}

But beware, this is can lead to a sort of multiple inheritance which may make your code harder to reason about.

2 Comments

Should the BaseService implement Service<T>??
@paramupk There is no Service<T> for that class to implement. You choose one or the other unless you are paid by the line. Prefer interfaces over abstract classes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.