• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Abstracting away an interface implementation

 
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Its generally accepted that an instance should be refernced through an interface rather than a concrete type.

Say you have an interface:


and an implementing class:


Conventional wisdom says we should declare vaiables of type Foo, and not FooImpl



My question is why not abstract away the concrete type altogether, and not give calling methods an oppertunity to assign a reference to the concrete implmentation.


That way it would be (nearly) impossible to reference any particular concrete type. I'm not sure if this is already a pattern but I think its kinda cool.
 
Ranch Hand
Posts: 490
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is assuming that you never want or need a concrete type. The principle, favor composition over inheritance does not mean never use inheritance.

It would probably be a good thing in narrow situations, but trying to enforce it across in many situations would be rather pointless. Take the String class, for an example. Use a Comparable reference, you have taken away all the functionality of that class, unless you cast it to a String. If your class only has those methods that are required through the implemented interfaces, it isn't a problem, but that is rarely the case.
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

The principle, favor composition over inheritance does not mean never use inheritance.

There is rarely (if ever) a situation where inheriting a concrete implementation is necessary. And some would argue that it is never a good thing.


It would probably be a good thing in narrow situations, but trying to enforce it across in many situations would be rather pointless. Take the String class, for an example. Use a Comparable reference, you have taken away all the functionality of that class, unless you cast it to a String.

Granted String is a unique case, but since you used it as your example, I was thinking more like if String was an interface that extended the Comparable, and CharSequence interfaces and defined the rest of its method in the String interface, then we could always refer to the String interface and never be coupled to any particular String implmentation.

If your class only has those methods that are required through the implemented interfaces, it isn't a problem, but that is rarely the case.

Obviously thats true for standard library classes, but there is nothing keeping one from defining all the methods in a custom class through an interface.
[ June 03, 2006: Message edited by: Garrett Rowe ]
 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


My question is why not abstract away the concrete type altogether, and not give calling methods an oppertunity to assign a reference to the concrete implmentation.


You're quite spot-on with your reasoning. In fact, you can extend it to draw some quite profound conclusions. In any case, to cover your scenario, take a look at ContractualJ, which covers your issue - and many more that are related. Simply, for any given concrete type T, it is impossible to assign that type T without a compile-time error (excluding the dynamically-typed literal null).
e.g. T t = x; // compile-time error for all cases

This is the best case scenario for our given context (Java) - though as you might well have already discovered, it is extremely suboptimal. I assure you, that after drawing some of the conclusions that "go against the grain" of the establishment (and so you encounter conflict as the religious subscribers watch their beliefs crumble before their eyes (I have no better explanation?)), the question arises, "what's the right way?". The answer to this question is an incredibly joyous journey with some unfortunate paradoxes that cannot be eliminated.

I love questions posed by critical thinkers
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic