1

I was thinking about programming to interfaces and not to concrete classes, but I had a doubt: should any interface method be able to hold references to concrete classes?

Suppose the following scenarios:

1)

public interface AbsType1 {
    public boolean method1(int a); // it's ok, only primitive types here
}

2)

public interface AbsType2 {
    public boolean method2(MyClass a); // I think I have some coupling here
}

Should I choose a different design here in order to avoid the latter? e.g.

public interface MyInterface {} // yes, this is empty

public classe MyClass implements MyInterface {
    // basically identical to the previous "MyClass"
}


public interface AbsType2 {
    public boolean method2(MyInterface a); // this is better (as long as the
                                           // interface is really stable)
}

But there's still something that doesn't convince me... I feel uncomfortable with declaring an empty interface, though I saw someone else doing so. Maybe and Abstract Class would work better here?

I am a little bit confused.

EDIT:

Ok, I'll try to be more specific by making an example. Let's say I'm desining a ShopCart and I want of course to add items to the cart:

public interface ShopCart {
    public void addArticle(Article a);
}

Now, if Article were a concrete class, what if its implementation changes over time? This is why I could think of making it an Interface, but then again, it's probably not suitable at least at a semantic level because interfaces should specify behaviours and an Article has none (or almost none... I guess it's a sort of entity class).

So, probably I'm ending up right now to the conclusion that making Article an abstract class in this case would be the best thing... what do you think about it?

kelo
  • 489
  • 1
  • 11
  • 20
  • 1
    I can see things are ok – Sanjay Rabari Apr 14 '14 at 11:10
  • Why do you declare your interface empty? Aren't there any relevant public methods in `MyClass` that `AbsType` would care about? - If there are none, then maybe you're better off using generics for the class type. – JimmyB Apr 14 '14 at 11:16

3 Answers3

2

I would use interfaces because composition is much better than inheritance. "Should any interface method be able to hold references to concrete classes ?", why it shouldn't? Some classes within package are coupled, it's a fact and common use technique. When you marked this relation in interface then you see on which classes is dependent your implementation. Dependency or composition relations are not inheritance so a i would avoid abstract class.

  • I added an example... in that specific case you would avoid abstract class as well? What would you do? – kelo Apr 14 '14 at 15:01
  • We think similarly, i would also make Article abstract, this is clearly inheritance relation, but ShopCart specify behavior, which operates on entity Article so it should be interface. – Peter Wroblewski Apr 15 '14 at 08:27
1

In my opinion Interfaces are fine for all types where the implementation may vary. But if you define a module which introduces a new type, that isn't intended to have alternative implementations then there is no need to define it as an Interface in the first place. Often this would be over-design in my opinion. It depends on the problem domain and often on the way how support testing or AOP-weaving.

For example consider a 2D problem domain where you need to model a Location as a type. If it is clear that a Location is always represented by a x and y coordinate, you may provide it as a Class. But if you do not know which properties a Location could have (GPS data, x, y, z coordinates, etc.) but you rely on some behavior like distance(), you should model it as an Interface instead.

Harmlezz
  • 7,972
  • 27
  • 35
1

If there are no public methods which AbsType would access in MyClass then the empty interface is probably not a good way to go.

There is no interface declaration (contract) for static methods, which otherwise might make sense here.

So, if AbsType is not going to use any methods from MyClass/MyInterface, then I assume it's basically only storing the class object for some other purpose. In this case, consider using generics to make clear how you want AbsType to be used without coupling closely to the client's code, like

public class AbsType3<C extends Class<?>> {

  public boolean method3(T classType) {...}

}

Then you can restrict the types of classes to allow if needed by exchanging the <C extends Class<?>> type parameter for something else which may also be an interface, like <C extends Class<Collection<?>>>.

Empty interfaces are somewhat like boolean flags for classes: Either a class implements the interface (true) or it doesn't (false). If at all, these marker interfaces should be used to convey an significant statement about how a class is meant to be (or not to be) used, see Serializable for example.

JimmyB
  • 12,101
  • 2
  • 28
  • 44
  • I provided an example... in that case I think that there's no need to use generics. What do you think? – kelo Apr 14 '14 at 15:02
  • You're right. So if you want to actually use an object passed to your method you may go for any approach of interface, abstract class, or concrete class. To minimize coupling, I'd actually recommend using an interface. Of course, an interface cannot enforce a contract as much as a concrete implementation, but this is not necessarily a problem, if the interface is designed carefully. Otoh, as long as you don't use `final` methods in your (abstract) base implementation, there's no way to enforce a contract either; any method could be overridden with contract-violating behaviour. – JimmyB Apr 17 '14 at 08:14
  • Go for the interface. – JimmyB Apr 17 '14 at 08:15