Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics vs. Interfaces

I transitioned from Java 1.4(previous company) to Java 1.6 (new company). What I have observed that in case of 1.4 most of the proprietary frameworks were defined using interfaces and template patterns, whereas with 1.6 most of the frameworks are defined around generics.

While I am still trying to get a grip around Generics, my question is - Is this a right design approach? Interfaces make your design more flexible/decoupled. Whereas Generics, implement type safety and enforce you to pass around a specific type of class. Doesn't really help in decoupling your code. Is this correct?

One example -

public MyWizard extends SignupWizard<SignupSection, SignupObject, SignupListener, SignupView>{
}

instead the design would be more flexible if it was ..

public interface Wizardable{
  public SignableSection getSection();
  public SignableObject getSignableObject();
...
}

public MyWizard implements Wizardable{
....
}
like image 554
Win Man Avatar asked Feb 24 '10 22:02

Win Man


1 Answers

I wouldn't say anything was generics vs interfaces, each have their different needs and uses. Using generic parameters in the way mentioned in the original post serves multiple purposes. It allows developers to define the base classes that make up the field object types of the class. Using this, the developer can accept class objects as parameters which they can use reflection on to create the actual objects and set the fields, or just accept the entire object to set in the first place. The problem which relates to needing class objects rather than doing new T() or such is known as type erasure.

Another benefit of using generics is that you don't need to typecast all the time when using fields or methods from a superclass -- you personally know their types, but Java doesn't have that type information stored anywhere. An additional benefit is that all your getter / setter methods can use the generic parameters and expose a more sensible front to other objects which rely on the fact that you set up specialised fields in the aforementioned object.

The problem with using interfaces to do the same thing that generics does is that you need additional methods to access the specialised types and cast them, before returning them (or check incoming types and then set fields to the objects). It's making the design more complex, and doesn't really help with decoupling at all.

As I mentioned in a comment, any subclasses will set those type parameters and expose nothing to the user. So you can have something like class MegaSignupWizard extends SignupWizard<MegaSignupSection, MegaSignupObject, MegaSignupListener, MegaSignupView> and everything remains perfectly valid with MegaSignupWizard having access to specialised methods in the classes without any need to cast. Now that's cool :)

like image 199
Chris Dennett Avatar answered Sep 23 '22 14:09

Chris Dennett