Подтвердить что ты не робот

Каковы основные различия между OO в Smalltalk и Java?

Каковы основные различия между OO в Smalltalk и Java?

Обратите внимание, что я программист Java, пытающийся расширить его горизонты, изучая Smalltalk. В настоящее время я почти ничего не знаю о Smalltalk, за исключением того, что он чище, чем Java. Поэтому я предпочел бы ответ, который показывает, как различные концепции Java сопоставляются с соответствующими концепциями Smalltalk, а затем вводит концепции Smalltalk, которые вообще не существуют в Java.

4b9b3361

Ответ 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 для выполнения.

Ответ 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 у вас нет вложенного класса.

...