En la programación orientada a objetos , la cascada de métodos es una sintaxis que permite llamar a varios métodos en el mismo objeto. Esto se aplica especialmente en interfaces fluidas .
Por ejemplo, en Dart , la cascada:
a..b ( ) .. c () ;
es equivalente a las llamadas individuales:
a.b ( ) ; a.c ( ) ;
La conexión en cascada de métodos es mucho menos común que el encadenamiento de métodos : se encuentra solo en un puñado de lenguajes orientados a objetos, mientras que el encadenamiento es muy común. Se puede implementar una forma de conexión en cascada mediante el encadenamiento, pero esto restringe la interfaz; consulte la comparación con el encadenamiento de métodos a continuación.
La sintaxis en cascada elimina la necesidad de enumerar el objeto repetidamente. Esto se utiliza especialmente en interfaces fluidas , que incluyen muchas llamadas a métodos en un solo objeto.
Esto es particularmente útil si el objeto es el valor de una expresión extensa, ya que elimina la necesidad de enumerar la expresión repetidamente o usar una variable temporal. Por ejemplo, en lugar de enumerar una expresión repetidamente:
a . b (). c (); a . b (). d ();
o usando una variable temporal:
n = a . b (); n . c (); n . d ();
La cascada permite escribir la expresión una vez y usarla repetidamente:
a . b ().. c () .. d ();
Dada una llamada a un método a.b()
, después de ejecutar la llamada, la cascada de métodos evalúa esta expresión en el objeto izquierdoa
(con su nuevo valor, si está mutado), mientras que el encadenamiento de métodos evalúa esta expresión en el objeto derecho .
La siguiente cadena (en C++):
a . b () . c ();
es equivalente a la forma simple:
b = a . b (); b . c ();
La siguiente cascada (en Dart):
a..b ( ) .. c () ;
es equivalente a la forma simple:
a.b ( ) ; a.c ( ) ;
La conexión en cascada se puede implementar en términos de encadenamiento haciendo que los métodos devuelvan el objeto de destino (receptor, this
, self
). Sin embargo, esto requiere que el método ya esté implementado de esta manera (o que el objeto original esté envuelto en otro objeto que haga esto) y que el método no devuelva algún otro valor potencialmente útil (o nada si eso fuera más apropiado, como en el caso de los setters). En las interfaces fluidas, esto a menudo significa que los setters devuelven esto en lugar de nada.
Dentro de la declaración de componente de la declaración with, los componentes (campos) de la variable de registro especificada por la cláusula with pueden ser denotados únicamente por su identificador de campo, es decir, sin precederlos con la denotación de la variable de registro completa. La cláusula with abre efectivamente el ámbito que contiene los identificadores de campo de la variable de registro especificada, de modo que los identificadores de campo pueden aparecer como identificadores de variable.
con fecha hacer si mes = 12 entonces empezar mes := 1 ; año := año + 1 fin sino mes := mes + 1 { es equivalente a } si fecha . mes = 12 entonces inicio fecha . mes := 1 ; fecha . año := fecha . año + 1 fin de lo contrario fecha . mes := fecha . mes + 1
Tanto las cadenas de métodos como las cascadas se introdujeron en Smalltalk ; la mayoría de los lenguajes orientados a objetos posteriores han implementado cadenas, pero pocos han implementado cascadas. En Smalltalk, el operador de punto y coma se puede utilizar para enviar diferentes mensajes al mismo objeto: [1]
listPane padre color: Color negro ; altura : 17 ; ancho: 11
Compárese con declaraciones separadas, terminadas con un punto, que también utilizan una variable como abreviatura:
| padre | padre := self listPane padre . padre color: Color negro . padre alto: 17 . padre ancho: 11 .
Una sutileza es que el valor de una llamada de método ("mensaje") en una cascada sigue siendo el valor normal del mensaje, no el del receptor. Esto es un problema cuando se desea el valor del receptor, por ejemplo, al crear un valor complejo. Esto se puede solucionar utilizando el yourself
método especial que simplemente devuelve el receptor: [2]
Objeto >> tú mismo ^ yo mismo
Por ejemplo, el método "agregar un objeto a una colección" ( Collection>>add: anObject
) devuelve el objeto que se agregó, no la colección. Por lo tanto, para usar esto en una cascada en una declaración de asignación, la cascada debe terminar con yourself
, de lo contrario, el valor será solo el último elemento agregado, no la colección en sí:
todo := OrderedCollection nuevo agregar: 5 ; agregar: 7 ; usted mismo .
Visual Basic utiliza la instrucción With para habilitar una cantidad arbitraria de llamadas a métodos o accesos a propiedades en el mismo objeto:
Con ExpressionThatReturnsAnObject . SomeFunction ( 42 ) . Property = value Terminar con
With..End With
Los bloques en Visual Basic se pueden anidar:
Con ExpressionThatReturnsAnObject . SomeFunction ( 42 ) . Property = value Con . SubObject . SubProperty = otherValue . AnotherMethod ( 42 ) Terminar con Terminar con
Entre los lenguajes más nuevos, Dart..
implementa cascadas, utilizando una "operación de invocación de método en cascada" con dos puntos . A diferencia de Smalltalk, en Dart el valor de una invocación de método en cascada es el receptor (objeto base), no el valor de la invocación de método (no en cascada), y por lo tanto no hay necesidad de yourself
. Dart utiliza propiedades y, por lo tanto, en lugar de utilizar la sintaxis de método para los métodos get y setter ( foo.getBar(); foo.setBar(b);
), utiliza la sintaxis de valor de campo/asignación ( foo.bar; foo.bar = b;
), y las cascadas funcionan con asignaciones:
a .. string = '¡Hola mundo!' .. done = true ;
es equivalente a:
a . string = '¡Hola mundo!' ; a . done = true ;