En programación de computadoras , la escritura del pato es una aplicación de la prueba del pato ("Si camina como un pato y grazna como un pato, entonces debe ser un pato") para determinar si un objeto puede usarse para un propósito particular. Con la tipificación nominativa , un objeto es de un tipo determinado si se declara como tal (o si la asociación de un tipo con el objeto se infiere mediante mecanismos como la herencia de objetos ). Con la escritura pato, un objeto es de un tipo determinado si tiene todos los métodos y propiedades requeridos por ese tipo. [1] [2] La tipificación Duck puede verse como una equivalencia estructural basada en el uso entre un objeto determinado y los requisitos de un tipo.
Este sencillo ejemplo en Python 3 demuestra cómo cualquier objeto puede usarse en cualquier contexto hasta que se use de una manera que no admite.
clase pato : Definitivamente nadar ( yo ): imprimir ( "Pato nadando" ) def volar ( yo ): imprimir ( "Pato volando" )clase ballena : Definitivamente nadar ( yo ): imprimir ( "Ballena nadando" )para animal en [ Pato (), Ballena ()]: animal . nadar () animal . volar ()
Producción:
Pato nadando Pato volando Ballena nadando AttributeError: el objeto 'Ballena' no tiene el atributo 'volar'
Si se puede suponer que cualquier cosa que pueda nadar es un pato porque los patos pueden nadar, una ballena podría considerarse un pato; sin embargo, si también se supone que un pato debe ser capaz de volar, la ballena no será considerada pato.
En algunos lenguajes de tipo estático, como Boo [3] y D , se puede especificar que la verificación del tipo de clase [4] [5] ocurra en tiempo de ejecución en lugar de en tiempo de compilación.
La tipificación de pato es similar a la tipificación estructural , pero distinta de ella . La tipificación estructural es un sistema de tipificación estática que determina la compatibilidad y equivalencia de tipos según la estructura de un tipo, mientras que la tipificación pato es dinámica y determina la compatibilidad de tipos solo por la parte de la estructura de un tipo a la que se accede durante el tiempo de ejecución .
Los lenguajes TypeScript , [6] Elm [7] y Python [8] admiten la tipificación estructural en diversos grados.
Los protocolos y las interfaces proporcionan una manera de declarar explícitamente que se deben definir algunos métodos, operadores o comportamientos. Si una biblioteca de terceros implementa una clase que no se puede modificar, un cliente no puede usar una instancia de ella con una interfaz desconocida para esa biblioteca incluso si la clase satisface los requisitos de la interfaz. Una solución común a este problema es el patrón de adaptador . Por el contrario, con la escritura pato, el objeto se aceptaría directamente sin necesidad de un adaptador.
Las funciones o métodos de plantilla (también llamados genéricos ) aplican la prueba de pato en un contexto de escritura estática ; esto trae todas las ventajas y desventajas de la verificación de tipos estática versus dinámica . La tipificación Duck también puede ser más flexible en el sentido de que solo se deben implementar los métodos realmente llamados en tiempo de ejecución, mientras que las plantillas requieren implementaciones de todos los métodos que no se pueden demostrar como inalcanzables en tiempo de compilación.
En lenguajes como Java, Scala y Objective-C, se puede emplear la reflexión para inspeccionar si los objetos implementan métodos o agregan los métodos necesarios en tiempo de ejecución. Por ejemplo, la API MethodHandle de Java se puede utilizar de esta manera. [9]