Могут ли операторы в Smalltalk быть перегружены? - PullRequest
6 голосов
/ 30 июня 2011

Возможно ли перегрузить операторов в Smalltalk?

Я ищу учебники / примеры.

Спасибо.

Ответы [ 5 ]

16 голосов
/ 30 июня 2011

Перегрузка метода невозможна в Smalltalk.Вместо этого комбинация переопределения метода и техники, называемой double dispatch , используется для реализации того же поведения, что и перегрузка операторов в других языках.

Пример реализации можно найти в математических операторах +,*,/,- (которые являются двоичными сообщениями в Smalltalk).Идея такова: реализация Integer>>+ отправляет сообщение #addWithInteger: в свой аргумент.Реализация #addWithInteger: реализована на каждом подклассе Magnitude, например, для специализированного добавления Int + Int, Float + Int и т. Д. *

12 голосов
/ 30 июня 2011

В большинстве случаев операторы на других языках находятся в унарных или двоичных сообщениях Smalltalk, таких как +, *, /, ... и т. Д. Классы могут свободно отвечать на эти сообщения, когда они кажутся подходящими, так что да может переопределить поведение +, и вы также можете заставить экземпляры некоторых нечисловых классов понимать и отвечать на него.

Например, посмотрите на реализацию + в классе Point.

Стоит отметить, что = и ^ не являются сообщениями, поэтому их нельзя переопределить, как описано выше.

Кстати, для изучения Smalltalk, одним из величайших источников примеров и кода является образ Smalltalk. Поэтому я рекомендую вам запустить Smalltalk и научиться просматривать огромное количество примеров, которые он содержит.

6 голосов
/ 30 июня 2011

В smalltalk нет операторов, кроме присваивания.Все реализовано в классах как методы.Поэтому, если вы хотите изменить поведение методов = или + / -, просто посмотрите на их разработчиков.Или, если вы хотите, чтобы экземпляры вашего класса понимали эти сообщения, просто реализуйте их.

1 голос
/ 17 ноября 2015

Тег operator-overloading определен в переполнении стека как

функция языка программирования, которая позволяет настраивать реализации для операторов в зависимости от типов используемых операндов.Некоторые языки позволяют определять новые операторы, в то время как другие допускают только переопределение существующих.

В Smalltalk
Все типы определены как классы объекта *
Все операторы являются методами *
Все методы выполняются получателем сообщения с именем метода
Все методы могут быть переопределены

Таким образом, любой оператор, работающий с любым операндом, может быть переопределен любым разработчиком.

Вот несколько примеров:
Объекты класса Float, класса SmallInt, класса Fraction и класса Point могут ответить на сообщение +.Они также могут взаимодействовать друг с другом.
aFloat := 3.1415 . aSmallInt := '6' . aPoint := 3@3 . aFraction := 22/7 .

"отправить сообщение + aSmallInt на aFraction"
aSum := aFraction + aSmallInt Оценивает: 64/7

"отправьте сообщение + aFraction aSmallInt"
aSum := aSmallInt + aFraction Оценивает: 64/7

aSum := aFloat + aFraction aSum := aFraction + aFloat Они оценивают: 6.284357142857143

aSum := aFloat + aSmallInt aSum := aSmallInt + aFloatОни оценивают: 9.1415

aSum := aPoint + aSmallInt aSum := aSmallInt + aPoint Они оценивают: 9@9

В действительности, у нас есть 8 различных реализаций оператора + на дисплее, каждая из которых настроена наиметь дело с типами задействованных операндов.

Предостережения: * Объекты не являются строго типизированными.Любая переменная одного типа может быть изменена на любой другой тип, и система не вызовет исключение.Объект может начинаться как объект класса SmallInt, а затем может быть изменен на ByteString или Dictionary, и система не выдаст ни малейшего предупреждения.Пока не отправлено сообщение, которое он не понимает.

Существует 6 примитивов, которые не являются объектом или классом объекта: true, false, nil и т. Д.

Есть два операторакоторые, по сути, являются синтаксическим сахаром для именованных методов.

0 голосов
/ 23 июня 2019

Smalltalk не имеет операторов, но вы можете добиться аналогичных результатов с помощью определения / переопределения метода:

Object subclass: Foo [ 
  + anObject [
    "define new behavior for + here"

  ]
]
...