Каковы основные различия между ОО в Smalltalk и Java? - PullRequest
38 голосов
/ 23 июня 2010

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

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

Ответы [ 7 ]

39 голосов
/ 23 июня 2010

Передача сообщений

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]

И обратите внимание на все эти [] s - первоклассные замыкания с чистым синтаксисом.

19 голосов
/ 25 июня 2010
  1. Модель объекта. В Smalltalk каждая вещь является объектом. У Java есть примитивные типы, такие как int и float, представление и поведение которых отличаются от сложных объектов.
  2. Вызов поведения. Поведение объекта Smalltalk вызывается путем отправки ему сообщения. У Java есть методы, которые в основном являются вызовами функций, с целевым объектом, являющимся специальным первым аргументом, называемым this.
  3. Инкапсуляция. Smalltalk имеет строгую инкапсуляцию. Поля объекта могут быть открыты только через сообщения. Java, напротив, допускает открытые поля.
  4. Динамизм. Smalltalk чрезвычайно динамичен. Все типы определяются во время выполнения. Класс может быть подвергнут интроспекции и изменению во время выполнения (динамическое метапрограммирование!). Новые классы могут быть созданы и созданы во время выполнения. У Java есть статическая проверка типов наряду с полиморфизмом времени выполнения. Существует самоанализ и рефлексия, но классы и объекты нельзя изменить из запущенной программы.
  5. Синтаксис. Smalltalk не имеет синтаксиса. Вместо этого он имеет простой, согласованный формат для отправки сообщений. Java, как и другие языки семейства C, имеет сложный синтаксис.
  6. Среда. Большинство реализаций Smalltalk предоставляют полную автономную живую вычислительную среду с постоянством на основе изображений . Некоторые из этих сред могут быть загружены даже на голом металле . JVM, в свою очередь, обычно зависит от базовой операционной системы для организации потоков, работы в сети и т. Д. Исходный код должен быть введен в текстовые файлы, скомпилирован и явно загружен в JVM для выполнения.
18 голосов
/ 23 июня 2010

Ключевым отличием Java от Smalltalk является то, что в Smalltalk есть класс первого класса (без каламбура).

Класс в Smalltalk - это объект. Наиболее близким к методу и переменной static является метод и переменная на уровне класса, как упомянул Фрэнк Ширер .

Но эта разница становится более глубокой, как только наследование используется. В Java наследование на стороне класса не существует, а в Smalltalk это возможно.

Если класс A наследуется от B, и если у вас есть a и b, которые являются экземплярами A и B, в Smalltalk, b class наследуется от a class. Это не будет иметь место в Java, где a getClass() и b getClass() возвращают экземпляры Class, которые не связаны друг с другом.

Скажем теперь, что класс A реализует шаблон синглтона: у него есть поле на стороне класса instance и метод получения instance. Класс B - это еще один объект со своим собственным полем instance. Как следствие, A instance и B instance вернут другой объект.

Это одно из главных отличий между Smalltalk и Java с точки зрения ОО.

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

И, конечно, у Smalltalk есть закрытие, которого до сих пор нет в Java.

См. Также Почему Java не позволяет переопределять статические методы?

12 голосов
/ 24 июня 2010

пытается расширить свой кругозор исследуя Smalltalk

Если вы активно пытаетесь исследовать Smalltalk, тогда вам нужно уметь читать Smalltalk -

«Я могу читать C ++ и Java, но не могу читать Smalltalk» pdf

8 голосов
/ 24 июня 2010

Одна концепция 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 голосов
/ 23 июня 2010

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

5 голосов
/ 23 июня 2010

Когда @ Янко Мившек имеет в виду все, он действительно имеет в виду все. :)

Даже до отправки сообщения вы создаете объект, который является контекстом.

Также в smalltalk у вас нет модификатора доступа (приватный / защищенный / публичный) У вас нет пакета в какой-либо реализации Smalltalk, и в большинстве пакетов реализации Smalltalk нет такой же семантики, как в Java.

В smalltalk у вас нет управляющей структуры, например, для try / catch ... Круто то, что они вам не нужны, потому что в smalltalk у вас есть закрытие блока.

В smalltalk у вас нет статического члена, вместо этого у вас есть класс, который является объектом (вы можете отправить сообщение классу, вы также можете хранить класс в переменной).

В smalltalk у вас нет вложенного класса.

...

...