With interfaces, it's pretty simple to replicate patterns like a Container<Comparable> or Channel<Reader>, to borrow common Java syntax. Personally, I like how it forces you to think about parametricity whenever you want polymorphism, like most functional languages.
But, unless I'm missing something, it's missing the supporting bits you get in a nice functional language, like algebraic datatypes and pattern matching, which make that style much more pleasant.
Of course, most of the functional language DO have generics, and full type inference to boot, also.
Up until the point you want to return an object from your container, sure. Then you have to return a Comparable and the user has to downcast it into the right object.