Каковы основные различия между OO в Smalltalk и Java?
Каковы основные различия между OO в Smalltalk и Java?
Обратите внимание, что я программист Java, пытающийся расширить его горизонты, изучая Smalltalk. В настоящее время я почти ничего не знаю о Smalltalk, за исключением того, что он чище, чем Java. Поэтому я предпочел бы ответ, который показывает, как различные концепции Java сопоставляются с соответствующими концепциями Smalltalk, а затем вводит концепции Smalltalk, которые вообще не существуют в Java.
Ответы
Ответ 1
Передача сообщений
Smalltalk использует передачу сообщений, а не вызов метода. Различие тонкое, но чрезвычайно мощное.
Некоторая терминология: если задано foo bar: baz
, #bar:
является селектором, foo является получателем сообщения с именем #bar:
(символ # указывает на символ, похожий на Common Lisp, говорит 'bar
(или даже более подходящим образом, :bar
)), а baz
является аргументом или параметром. Когда строка выполнена, foo
отправляется сообщение #:bar:
с аргументом baz
. Пока это довольно нормально. В Java это будет выглядеть как foo.bar(baz);
.
В Java система времени выполнения определит фактический тип foo
, найдет наиболее подходящий метод и запустит его.
В Smalltalk все выглядит примерно так же. Когда вы отправляете сообщение об объекте, он ищет в своем словаре метода метод, имя которого совпадает с именем селектора сообщения. Если он не может найти его, он ищет в своем словаре методов суперкласса и т.д. Довольно нормальный материал.
Если он не может найти какой-либо метод сопоставления, он отправляет сообщение #doesNotUnderstand:
с исходным сообщением в качестве параметра. (Да, отправка сообщения - это объект.) Но #doesNotUnderstand:
также является просто методом. Вы можете переопределить его.
Например, вы можете иметь объект, который отвечает на какой-либо набор сообщений при пересылке любых других сообщений, которые он получает, на какой-либо объект-делегат. Переопределите #doesNotUnderstand:
и эй престо, у вас есть прокси-сервер, который не нуждается в обслуживании, чтобы синхронизировать его протокол с делегатом.
Тривиальный синтаксис
Нет, я не шучу. Smalltalk всей грамматики может быть 15 строк длиной. JLS - это... нет. Зачем заботиться? Простой синтаксис упрощает разрывание фрагмента кода. Метапрограммирование! Рефакторинг!
Нет синтаксиса для:
- условные операторы:
(n < 3) ifTrue: ['yes'] ifFalse: ['no']
- для циклов:
1 to: 10 do: [:i | Transcript show: i asString]
- try-catch:
[i := i / 0] ifError: ['oops!']
- try-finally:
[i := i / 0] ensure: [stream close]
И обратите внимание на все те []
- первоклассные закрытия с чистым синтаксисом.
Ответ 2
Ключевое различие между Java и Smalltalk заключается в том, что Smalltalk имеет первоклассный класс (каламбур не предназначен).
Класс в Smalltalk является объектом. Самое близкое к методу и переменной static
- это метод и переменная класса, как упомянутый, написанный Франком Ширером.
Но это различие более глубокое, как только наследование используется. В java class-side наследование не существует, в то время как это возможно в Smalltalk.
Если класс A
наследуется от B
, и если у вас есть A
и B
, которые являются экземплярами A
и B
, в Smalltalk b class
наследуется от a class
. Это было бы не так в Java, где a getClass()
и b getClass()
возвращают экземпляры Class
, которые не связаны друг с другом.
Теперь скажем, что класс A
реализует одноэлементный шаблон: он имеет поле класса instance
и метод getter instance
. Класс B
- это еще один объект со своим собственным полем instance
. Как следствие, A instance
и B instance
возвращают другой объект.
Это, безусловно, одно из основных различий между Smalltalk и Java с точки зрения OO.
Другая разница заключается в существовании метаклассов, методов расширения, утиной печати и статической типизации, овеществлении doesNotUnderstand
и нескольких других вещей, которые делают кодирование в Smalltalk или Java совершенно другим.
И, конечно, Smalltalk имеет закрытие, которое Java все еще не хватает.
См. также Почему Java не позволяет переопределять статические методы?
Ответ 3
- Объектная модель. В Smalltalk всякая вещь - это объект. Java имеет примитивные типы, такие как int и float, представление и поведение которых отличаются от сложных объектов.
- Вызов поведения. Поведение объекта Smalltalk вызывается, отправив ему сообщение. Java имеет методы, которые являются в основном вызовами функций, причем целевой объект является специальным первым аргументом
this
.
- Инкапсуляция. Smalltalk имеет строгую инкапсуляцию. Поля объектов могут отображаться только через сообщения. Напротив, Java разрешает публичные поля.
- Динамизм. Smalltalk чрезвычайно динамичен. Все типы идентифицируются во время выполнения. Класс можно интродуцировать и модифицировать во время выполнения (динамическое метапрограммирование!). Новые классы можно создавать и создавать экземпляры во время выполнения. Java имеет проверку статического типа вместе с полиморфизмом времени выполнения. Существует интроспекция и отражение, но классы и объекты не могут быть изменены из запущенной программы.
- Синтаксис. Smalltalk не имеет синтаксиса. Вместо этого он имеет простой, согласованный формат для отправки сообщений. Java, как и другие языки семейства C, имеет сложный синтаксис.
- Среда.. Большинство реализаций Smalltalk предоставляют полную, автономную, живую вычислительную среду с устойчивостью к изображениям. Некоторые из этих сред могут даже загружаться на голом металле. JVM, в свою очередь, обычно зависит от базовой операционной системы для потоковой передачи, создания сетей и т.д. Исходный код должен быть введен в текстовые файлы, скомпилирован и явно загружен в JVM для выполнения.
Ответ 4
пытается расширить свои горизонты изучение Smalltalk
Если вы активно пытаетесь изучить Smalltalk, вам нужно знать, как читать Smalltalk -
"Я могу читать С++ и Java, но я не могу читать Smalltalk" pdf
Ответ 5
В Smalltalk все является объектом, в то время как в Java такие вещи, как маленькие целые, все еще не являются объектами первого класса. Кроме того, чтобы продолжить с числами, в Smalltalk из-за его чистой природы OO и сильных отражающих способностей нам никогда не нужно заботиться о размере числа, например, если целое число мало или велико, и что происходит, когда малые целые числа переполняются до больших.
Ответ 6
Одна концепция Smalltalk, которая не существует на Java, но становится все более популярной в последние годы, - это блоки. Блоки - это форма анонимных функций, которые включают контекст, в котором они были определены. Важно отметить, что блоки также являются объектами. На Smalltalk фактически не было никакого встроенного if
-statement или for
-loop или чего-то подобного, но удалось создать тот же эффект только с передачей сообщений и блоками.
object isBig ifTrue: [self runIntoObject:object]
ifFalse: [self katamariBall absorbObject:object].
1 to: 10 do: [:number | number print]
Ответ 7
Когда @Janko Mivšek означает все, что он действительно имеет в виду.:)
Даже до отправки сообщения, что вы делаете, создается объект, являющийся контекстом.
То, что у вас нет в smalltalk, - это модификатор доступа (private/protected/public)
У вас нет пакета в какой-либо реализации Smalltalk, и в большинстве пакетов реализации Smalltalk нет такой же семантики, как Java.
В smalltalk у вас нет структуры управления, например, если, попробуйте/поймать... Классные вещи в том, что они вам не нужны, потому что у вас есть блокировка закрытия в smalltalk.
В smalltalk у вас нет статического члена, вместо этого у вас есть класс, являющийся объектом (вы можете отправить сообщение классу, вы также можете удерживать класс в переменной).
В smalltalk у вас нет вложенного класса.
...