In computer programming with object-oriented programming languages, duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface. The name of the concept refers to the duck test, attributed to James Whitcomb Riley, which may be phrased as follows:
when I see a bird thatwalk
s like a duck
andswim
s like a duck
andquack
s like a duck,
I call that bird a duck
In duck typing, one is concerned with just those aspects of an object that are used, rather than with the type of the object itself.
...
In a duck-typed language, the equivalent function would take an object of any type and call that object'swalk
andquack
methods. If the object does not have the methods that are called then the function signals a run-time error. It is this action of any object having the correctwalk
andquack
methods being accepted by the function that evokes the quotation and hence the name of this form of typing.
Duck
typing is aided by habitually not testing for the type of arguments in method and function bodies, relying on
- documentation,
- clear code,
- and testing
to ensure correct use. Users of statically typed languages new to dynamically typed languages are usually tempted to add such static (before run-time) type checks, defeating the benefits and flexibility of duck typing, and constraining the language's dynamism.Ejemplo:
generaciondecodigos@nereida:~/src/groovy/objects$ cat -n duckTyping.groovy 1 class Dog { 2 void speak() { print "guaguau! " } 3 void eat() { println "bones, bone, bon, bo, b" } 4 } 5 6 class Pig { 7 void speak() { print "oink, oink! " } 8 void eat() { println "fodder, fodde, fodd, fod, fo, f" } 9 } 10 11 def behave(animal) { 12 3.times { 13 animal.speak() 14 animal.eat() 15 } 16 } 17 18 (Fly, Babe) = [ new Dog(), new Pig() ] 19 behave(Fly) 20 behave(Babe)Ejecución:generaciondecodigos@nereida:~/src/groovy/objects$ groovy duckTyping.groovy guaguau! bones, bone, bon, bo, b guaguau! bones, bone, bon, bo, b guaguau! bones, bone, bon, bo, b oink, oink! fodder, fodde, fodd, fod, fo, f oink, oink! fodder, fodde, fodd, fod, fo, f oink, oink! fodder, fodde, fodd, fod, fo, fNo se comprueba de que clase es el parámetro
animal
pasado a la funciónbehaves
. Si puede llamar aspeak
y aeat
todo irá bien. De lo contrario obtendremos un error.
Ejemplo de Polimorfismo con Duck-Typing
generaciondecodigos@nereida:~/src/groovy/objects$ cat -n wikipduck.groovy 1 def calculate(a, b, c) { return (a+b)*c } 2 3 example1 = calculate (1, 2, 3) 4 example2 = calculate ([1, 2, 3], [4, 5, 6], 2) 5 example3 = calculate ('apples ', 'and oranges, ', 3) 6 7 println example1 8 println example2 9 println example3 10Thus, duck typing allows polymorphism without inheritance. The only requirement that function calculate needs in its variables is having the+
and the*
methods.generaciondecodigos@nereida:~/src/groovy/objects$ groovy wikipduck.groovy 9 [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6] apples and oranges, apples and oranges, apples and oranges,
Críticas
One issue with duck typing is that it forces the programmer to have a much wider understanding of the code he or she is working with at any given time. In a strongly and statically typed language that uses type hierarchies and parameter type checking, it's much harder to supply an unexpected object type to a class.
For instance, in Python, you could easily create a class calledWine
, which expects a class implementing the "press
" attribute. However, a class calledTrousers
might also implement thepress
() method. With Duck Typing, in order to prevent strange, hard-to-detect errors, the developer needs to be aware of each potential use of the method "press
", even when it's conceptually unrelated to what he or she is working on.
In essence, the problem is that, "if it walks like a duck and quacks like a duck", it could be a dragon doing a duck impersonation. You may not always want to let dragons into a pond, even if they can impersonate a duck.
Subsecciones Casiano Rodríguez León
2010-04-30