В объектно-ориентированном программировании каскадирование методов — это синтаксис , который позволяет вызывать несколько методов для одного и того же объекта. Это особенно применимо в текучих интерфейсах .
Например, в Dart каскад:
а .. б () .. в ();
эквивалентно отдельным вызовам:
а . б (); а . в ();
Каскадирование методов встречается гораздо реже, чем цепочка методов — оно встречается только в нескольких объектно-ориентированных языках, в то время как цепочка очень распространена. Форма каскадирования может быть реализована с помощью цепочки, но это ограничивает интерфейс; см. сравнение с цепочкой методов ниже.
Каскадирование — это синтаксический сахар , который устраняет необходимость в повторном перечислении объекта. Это особенно используется в текучих интерфейсах , которые содержат много вызовов методов для одного объекта.
Это особенно полезно, если объект является значением длинного выражения, поскольку это устраняет необходимость либо перечислять выражение повторно, либо использовать временную переменную. Например, вместо того, чтобы перечислять выражение повторно:
а . б (). в (); а . б (). г ();
или с использованием временной переменной:
n = а . б (); n . в (); n . г ();
Каскадирование позволяет записать выражение один раз и использовать его многократно:
а . б ().. в () .. г ();
При вызове метода a.b()
после выполнения вызова каскадирование методов вычисляет это выражение для левого объекта a
(с его новым значением, если оно изменено), в то время как цепочка методов вычисляет это выражение для правого объекта.
Следующая цепочка (на C++):
а . б (). в ();
эквивалентно простой форме:
б = а . б (); б . в ();
Следующий каскад (в Dart):
а .. б () .. в ();
эквивалентно простой форме:
а . б (); а . в ();
Каскадирование может быть реализовано в терминах цепочки, когда методы возвращают целевой объект (приемник, this
, self
). Однако для этого требуется, чтобы метод был реализован таким образом уже — или исходный объект был обернут в другой объект, который делает это — и чтобы метод не возвращал какое-либо другое, потенциально полезное значение (или ничего, если это было бы более уместно, как в сеттерах). В текучих интерфейсах это часто означает, что сеттеры возвращают это вместо ничего.
В операторе компонента оператора with компоненты (поля) переменной записи, указанной предложением with , могут быть обозначены только их идентификатором поля, т.е. без предшествующего им обозначения всей переменной записи. Предложение with фактически открывает область, содержащую идентификаторы полей указанной переменной записи, так что идентификаторы полей могут встречаться как идентификаторы переменных.
с датой сделать если месяц = 12 тогда начать месяц := 1 ; год := год + 1 конец иначе месяц := месяц + 1 { эквивалентно } если дата.месяц = 12 тогда начало дата.месяц : = 1 ; дата.год : = дата.год + 1 конец иначе дата.месяц : = дата.месяц + 1
Метод цепочки и каскады были введены в Smalltalk ; большинство последующих объектно-ориентированных языков реализовали цепочки, но лишь немногие реализовали каскады. В Smalltalk оператор точки с запятой может использоваться для отправки различных сообщений одному и тому же объекту: [1]
собственный родительский цвет listPane : Цвет черный ; высота: 17 ; ширина: 11
Сравните с отдельными операторами, заканчивающимися точкой, также использующими переменную для сокращения:
| родитель | родитель := self listPane родитель . цвет родителя : черный цвет . высота родителя : 17 . ширина родителя : 11 .
Одна тонкость заключается в том, что значение вызова метода («сообщение») в каскаде по-прежнему является обычным значением сообщения, а не получателя. Это проблема, когда вам нужно значение получателя, например, при построении сложного значения. Это можно обойти, используя специальный yourself
метод, который просто возвращает получателя: [2]
Объект >> себя ^ себя
Например, метод "добавить объект в коллекцию" ( Collection>>add: anObject
) возвращает добавленный объект, а не коллекцию. Таким образом, чтобы использовать это в каскаде в операторе присваивания, каскад должен заканчиваться на yourself
, в противном случае значение будет просто последним добавленным элементом, а не самой коллекцией:
все := OrderedCollection новый добавить: 5 ; добавить: 7 ; себя .
Visual Basic использует оператор With для включения произвольного количества вызовов методов или доступа к свойствам одного и того же объекта:
С Выражением , КотороеВозвращаетОбъект.НекаяФункция ( 42 ) .Свойство = значение Конец с
With..End With
Блоки в Visual Basic могут быть вложенными:
С Выражением , КотороеВозвращаетОбъект.НекаяФункция ( 42 ) .Свойство = значение С ПодОбъектом.ПодСвойство = другоеЗначение.ДругойМетод ( 42 ) Конец С Конец С
Среди новых языков Dart реализует каскады, используя "операцию каскадного вызова метода" с двумя точками ..
. В отличие от Smalltalk, в Dart значением каскадного вызова метода является получатель (базовый объект), а не значение (некаскадного) вызова метода, и, таким образом, нет необходимости в yourself
. Dart использует свойства , и, таким образом, вместо использования синтаксиса метода для геттеров и сеттеров ( foo.getBar(); foo.setBar(b);
), он использует синтаксис значения поля/присваивания ( foo.bar; foo.bar = b;
), а каскады работают с присваиваниями:
a .. string = 'Привет, мир!' .. done = true ;
эквивалентно:
a . string = 'Привет, мир!' ; a . done = true ;