Java classes have to be declared to implement an interface. Haskell types don't need to be declared to "implement" a typeclass, since the typeclass instance is declared separately.
Let's be more specific: instances should be declared with the class or with the data type. Orphaned instances (that go with neither) are discouraged and with good reason - instances cannot be imported explicitly [1]. It is all to easy to have two conflicting instances if people start defining instances apart from the type class or data type. Don't do that! Luckily, -Wall will complain loudly about orphaned instances.
where you don't have the ability to freely modify any and all source included
Given the above, this is not really true in Haskell. Since orphaned instances are bad, people often wrap a data type using newtype and define the instances with that type. Of course, this is not so much different from creating a wrapper class in Java with another superclass or interface. Except that defining new types in Haskell comes with far less ceremony ;).
Duck typing is an exercise in ceremony reduction, ideally to the point of no ceremony at all. We can always add another layer of indirection to act as a proxy whatever language we choose. Java and similar OO languages make it harder, duck typing is the easiest it gets. Everything else is on a continuum.
FWIW, I was more interested in the implementation details of existential types, and how similar it is to Go (except that Go does it dynamically using reflection, last time I checked). You know more about Haskell and its idioms than I do, I just know about the features and make inferences from how they may be combined :)
Let's be more specific: instances should be declared with the class or with the data type. Orphaned instances (that go with neither) are discouraged and with good reason - instances cannot be imported explicitly [1]. It is all to easy to have two conflicting instances if people start defining instances apart from the type class or data type. Don't do that! Luckily, -Wall will complain loudly about orphaned instances.
where you don't have the ability to freely modify any and all source included
Given the above, this is not really true in Haskell. Since orphaned instances are bad, people often wrap a data type using newtype and define the instances with that type. Of course, this is not so much different from creating a wrapper class in Java with another superclass or interface. Except that defining new types in Haskell comes with far less ceremony ;).
[1] http://www.haskell.org/haskellwiki/Orphan_instance