This is really a good philosophical 'Talk', I'll give it a brief thinking through.
http://video.google.com/videoplay?docid=2159021324062223592&q=tech+talk&total=878&start=0&num=10&so=0&type=search&plindex=1
In contructing computer systems I have discovered that categorization itself can be a constriction, that ultimately can lead to severe problems.
For an example in java you have inheritance. As a rule in new generations of development processes everything should be refactorable with the least amount of effort. How can you then defend defining some objects parents, from which all attributes are set in stone. This really emphasizes the problem of the fragile base class. I have seen this sometimes and I have'nt really made any really programmed on any system of a size where changing the baseclass would cost more than a few days of work.
So the definition of anything by it's mere name or conception is fundamnetally flawed in programming. Instead it should be defined by its behaviour. This is generally enforced in the java language, so I can't help wonder why the Class inheritance construct is still is use.
In short, never think you have completely defined anything in you domain. Use interfaces always. Don't extend anything! Always assume that your definition of something will change.
Currently I'm tackling problems with an old system, which really was not designed for the features it now supports. One problem is that in the system a 'Product' is very well defined. So well defined, that changing its structure is basically a rewrite. The product should instead have been defined through interfaces. So a function changing a products price would use it's interface to that extent. A 'pricable' interface perhaps. Define it by behaviour!
I work with software development as a freelance developer.