Start  |  Gry  |  Słowniki *  
 : : Menu
Dla początkujących
Dla praktyków
Język
Wersje
Książki
Smalltalk vs. Java
Wiadomości
Linki
FAQ
Pobierz
Co nowego?
Mapa serwisu
Kontakt
Impressum
Księga gości
Po godzinach
Nakarm głodne dziecko - wejdź na stronę www.Pajacyk.pl
 

Porównanie języków Smalltalk i Java

Strona ta jest tworzona na bieżąco. Jezeli programujesz w Smalltalku lub Javie i możesz podzielić się swoją wiedzą napisz do mnie: .
  • Język
  • Aspekty techniczne
    • Maszyna wirtualna
    • Kompilator
    • Garbage Collection
    • Procesy / wątki
    • Pliki tekstowe / image
    • Packages / Namespaces
  • Aspekty teoretyczne
    • Enkapsulacja
    • Polimorfizm
    • Późne łączenie
    • Typizacja
  • Aspekty praktyczne
    • Implementacje i środowiska programistyczne
    • Wspierane platformy
    • Wspierane bazy danych
    • Elastyczność
    • Standardy dokumentowania kodu
  • Aspekty ekonomiczne
    • Wydajność programisty
    • Stabilność
    • Koszty
    • Niezależność





Język

Składnia

Komentarze
  • Smalltalk

Komentarz w języku Smalltalk umieszczony jest między znakami cudzysłowia. Wszystko co znajduje się między tymi znakami nie jest kompilowane do image, lecz wyłącznie przechowywane w kodzie źródłowym.

"To jest przykładowy komentarz w Smalltalku"

  • Java

W Javie istnieją dwa rodzaje komentarzy - wielowierszowy:

/* To jest wielowierszowy komentarz w Javie;
To jest drugi wiersz komentarza */

i pojedynczy, tylko na koncu wiersza:

// To jest pojedynczy komentarz w Javie




Typy danych

  • Smalltalk

Ponieważ Smalltalk jest językiem z dynamiczną typizacją oraz wszystkie jego elementy są obiektami nie istnieje rozróżnienie typów. Obiekty są rozróżniane jak instancje konkretnej klasy, np. liczba 26 jest instancją klasy Number.

  • Java

W Javie rozróżnia się między typami prymitywnymi i referencyjnymi.

Typy prymitywne, takie jak byte, short, int, long (liczby całkowite), float, double (liczby rzeczywiste), boolean (typ logiczny) i char (znaki) są pozostałością po proceduralnych językach C i C++. Zostały pozostawione między innymi ze względu na ich wydajność. W przeciwieństwie do Smalltalka nie są to obiekty. Oznacza to między innymi brak możliwości rozszerzenia ich funkcjonalności (w Smalltalku wystarczy zmodyfikować odpowiednią klasę, np. Number, Integer, String czy Boolean).

Pod pojęciem "typy referencyjne" kryją się klasy, interfejsy i ciągi (Arrays, a więc także ciągi znaków).

Zastosowanie typów prymitywnych w Javie ma też jeden skutek uboczny - liczby całkowite ulegają "przewijaniu" podczas operacji arytmetycznych.

Przykład:

short theInt = Short.MAX_VALUE;
theInt++;
System.out.println(theInt); // Wynik to -32768! Zakres liczb typu short uległ "przewinięciu"!

W Smalltalku natomiast wygląda to następująco:

| x |
x := SmallInteger maxVal.
x := x + 1.
x printString. "Wynik to 536870912. Wynik jest instancją klasy LargePositiveInteger."

Wprawdzie Java oferuje klasy opakowujące typy prymitywne (ang. wrappers), jednak nie są one w pełni funcjonalne, na przykład próba stworzenia nastepującego kodu:

Integer x = new Integer(1);
Integer y = new Integer(6);
x = x + y;

Spowoduje zgłoszenie błędu: "The operator + is undefined for the argument type(s) java.lang.Integer, java.lang.Integer".





Zmienne
  • Smalltalk

Smalltalk stosuje dynamiczną typizację. Typ zmiennej jest ustalany dopiero w czasie wykonywania programu. Przyczyną takiego rozwiązania jest fakt, że w Smalltalku wszystkie zmienne są adresami w pamięci czyli wskażnikami na obiekty umieszczone pod tymi adresami. Dlatego typ danej zmiennej może zostać określony dopiero po umieszczeniu konkretnego obiektu pod adresem jaki ona wskazuje. Programista w trakcie implementacji programu zauważa tę cechę jako brak konieczności deklaracji typu zmiennej i możliwość przypisania do zmiennej obiektu dowolnego typu.

Przykład:
x := 26.zmienna x "przechowuje" liczbę 26 (dokładniej wskazuje obszar pamięci pod którym znajduje się instancja klasy Integer ).
x := 'Hello'.x "przechowuje" ciąg znaków 'Hello' (instancję klasy String).
x := Array new.x "przechowuje" tablicę (instancję klasy Array).

Nazwy zmiennych w Smalltalku są ciągiem liter i cyfr, ale rozpoczynają się zawsze literą. Smalltalk rozróżnia duże i małe litery, a więc thevariable i theVariable to dwie różne zmienne.

Wszystkie nowe zmienne wskazują początkowo obiekt nil. W celu przypisania im wartości używany jest operator (metoda) ":="

  • Java

Java stosuje silną, statyczną typizację. Typ każdej zmiennej musi być określony w trakcie implementacji programu. To oznacza między innymi większy nakład pracy dla programisty, większą ilość kodu i mniejszą przejrzystość.

W celu przypisania wartości do zmiennej stosuje się operator "=".

Konwencja nazewnictwa jest w Javie następująca: nazwy klas i interfejsów rozpoczynają się wielką literą i mogą zawierać litery i cyfry (MyClass); stałe pisane są z reguły wielką literą (np. MY_CONST). Wszystko inne jest nazywane jak klasy, ale z małej litery. Java także rozróżnia małe i wielkie litery w nazwach zmiennych, klas i interfejsów (a więc np. myvar i myVar to dwie różne zmienne.).





Słowa kluczowe
  • Smalltalk

Smalltalk posiada tylko pięć słów kluczowych. Wszystko inne jest zrealizowane za pomocą klas.

"5 słów kluczowych w Smalltalku"
nil self super true false

  • Java

Java ma parę słów kluczowych więcej niż Smalltalk...

// 59 słów kluczowych w Javie
abstract boolean break byte byvalue case cast catch char class const continue default do double else extends false final finally float for future generic goto if implements import inner instanceof int interface long native new null operator outer package private protected public rest return short static super switch synchronized this throw throws transient true try var void volatile while




Literały
  • Smalltalk
Literał jest fragmentem kodu zamienianym przez maszynę wirtualną od razu w obiekt. Przykładem są słowa kluczowe, ale również:

"Przykłady literałów w Smalltalku"
'To jest literał' String
#atosymbolSymbol
-26Integer
-3.8Float
7/5Fraction
2r011Zapis dwójkowy
8r126Zapis ósemkowy
16r4AEZapis szesnastkowy
$CCharacter
#(1 2 3)Array (tablica) zawierająca liczby całkowite (Integer)
#( #(5 6 7) #(9 13 15))tablica zawierająca tablice
  • Java
Podobnie literały w Javie:

// Przykłady literałów w Javie
"To jest literał"String
-26Integer
-62876LLong
-3.8FFloat
-3.8, 4E-24Double
-026Zapis ósemkowy
-0x2FZapis szesnastkowy
'C'Character
{1, 2, 3}tablica zawierająca liczby całkowite
{{1, 2}, {3}, new int[0]}tablica zawierająca tablice




Wyrażenia
  • Smalltalk

W Smalltalku kolejne wyrażenia są tak jak normalnych zdaniach oddzielone kropką.

anObject doSomething.
anObject doSomethingElse.

Dodatkowo możliwe jest kaskadowanie wiadomości. Kolejne wiadomości wysyłane do danego obiektu są przedzielone średnikiem.

"Przykład wywołania kaskadowego"

anObject
   doSomething;
   doSomethingElse.


  • Java

W Javie do oddzielania wyrażeń stosuje się średnik.

anObject.doSomething();
anObject.doSomethingElse();

Możliwość kaskadowania wiadomości jest ograniczona do metod zwracających swojego odbiorcę (obiekt do którego zostały wysłane).

public class Example {

   public Example doSomething() {
      // (...) - tutaj znajduje się kod metody
      return this;
   }

   public Example doSomethingElse() {
      // (...) - tutaj znajduje się kod metody
      return this;
   }

   static public void main(String[] args) {
      Example ex = new Example();
      ex.doSomething().doSomethingElse(); // kaskadowanie
  }
}




Struktury sterujące
  • Smalltalk

W Smalltalku do sterowania wykonaniem aplikacji stosuje się metody ifTrue:, ifFalse:, ifTrue:ifFalse: i ifFalse:ifTrue: rozumiane przez obiekty true, false i nil.

(a > b)
   ifTrue: [ anObject doSomething ]
   ifFalse: [ anObject doSomethingElse ].

anObject isNil
   ifFalse: [ anObject doSomething ].

Wyrażenie [] jest blokiem kodu, czyli instancją klasy BlockClosure i jest tutaj argumentem wyżej wymienionych metod.

Smalltalk nie oferuje mechanizmu "switch". Artykuł "Mechanizm "switch-case" w Smalltalku" prezentuje prosty sposób realizacji tego mechanizmu.



  • Java

Java używa nieobiektowych struktur sterujących przejętych z języka C.

if (a > b) {
   anObject.doSomething()
   }
   else {
   anObject.doSomethingElse()
   }

Dodatkowo Java oferuje przejęty z języka C mechanizm switch.

switch (var) {
   case 1: return "aaa";
   case 2: return "bbb";
}

Mechanizm switch jest jednak ograniczony tylko do typów prymitywnych char, byte, short i int.





Pętle
  • Smalltalk

Pętle w Smalltalku są zrealizowane przez metody obiektów takich jak true, false i liczby.

(x > y) whileTrue: [].

(x > y) whileFalse: [].

10 timesRepeat: [].

1 to: 10 do: [:i | i := i + 1].

1.5 to: 9.5 by: 0.5 do: [:i | i := i + 1].

Wyrażenie [] jest blokiem kodu, czyli instancją klasy BlockClosure i jest tutaj argumentem wyżej wymienionych metod.

Jak widać Smalltalk stosuje konsekwentnie podejście obiektowe - pętle są normalnymi metodami zaimplementowanymi w konkretnych klasach.
  • Java

Java stosuje nieobiektowe struktury przejęte z języka C.

for(wyrażenie inicjujące; wyrażenie logiczne; zmiana indeksu) {}

while (wyrażenie logiczne) {}

do {} while (wyrażenie logiczne)




Klasy
  • Smalltalk

Klasy w Smalltalku również są obiektami, dlatego nową klasę tworzy się wysyłając do klasy, od której nowa klasa ma zostać wyprowadzona (przyszłej nadklasy) komunikat tworzący nową klasę, np. subclass:instanceVariableNames:classvariableNames:poolDictionaries:category:.

Klasa i jej metody są kompilowane niezależnie od siebie, nowe metody mogą zostać dodane do klasy, a już istniejące zmienione w każdej chwili, nawet w trakcie działania aplikacji wykorzystującej daną klasę.

  • Java

Nowe klasy tworzy się w pliku o takiej samej nazwie jak nazwa klasy i dodaje do niego definicję klasy. Każda poważniejsza zmiana, np. dodanie metody wymaga ponownej kompilacji danej klasy.





Metody
  • Smalltalk

W Smalltalku rozróżnia się trzy rodzaje metod: unarne, binarne i wieloargumentowe, składające się z jednego lub kilku słów kluczowych (ang. keyword).

Metoda unarna nie wymaga argumentów:

1.0 sin "Zwraca sinus z liczby 1.0"
Array new. "Zwraca pustą tablicę"
Date today. "Zwraca aktualną datę"

Metoda binarna używa znaku specjalnego, na przykład znaku "+", jako swojej nazwy i posiada dokładnie jeden argument. Niektóre wiadomości binarne składają się z kombinacji dwóch znaków specjalnych, na przykład operator porównania ">=".

1 + 2 "Dodawanie"
a <= b. "Porównanie"
10 @ 12. "Tworzy instancję klasy Point"

Metody wieloargumentowe składają się z jednego lub więcej słów kluczowych, zakończonych dwukropkiem po którym następuje argument metody.

Array new: 5. "Tworzy tablicę pięcioelementową"

Rectangle left: 2 top: 4 right: 10 bottom: 12. "Tworzy kwadrat"

'abcdefgh' copyFrom: 2 to: 5. "Kopiuje elementy od 2 do 5 do nowej instancji klasy String"

 

  • Java

Metody w Javie są tworzone w starej konwencji C. Wiadomości są wysyłane do odbiorcy za pomocą operatora "." (kropka). Ewentualne argumenty znajdują sę w nawiasach, po nazwie metody.

// Metoda bez argumentów
anObject.message();

// Metoda z jednym argumentem
anObject.message(a);

// Metoda wieloargumentowa
anObject.message(a, b);



Tworzenie instancji klasy Rectangle wyglądałoby w obu językach następująco:

Smalltalk

Rectangle
   left: 2
   top: 4
   right: 10
   bottom: 12. "Tworzy kwadrat"

Java

new Rectangle(2,4,10,12);

Jak widać czytając kod Smalltalkowy można od razu zrozumieć operację jaka jest wykonywana i znaczenie argumentów metody, bez znajomości klasy Rectangle.





Bloki
  • Smalltalk

Blok kodu jest w Smalltalku normalnym obiektem, instancją klasy BlockClosure. Tworzy się go za pomocą nawiasów klamrowych "[]". Blok kodu może zawierać wiele instrukcji Smalltalkowych, zostaną one wykonane po wysłaniu do bloku wiadomości value lub jednej z jej odmian:

value: anObject
value: anObject value: anObject
value: anObject value: anObject value: anObject
valueWithArguments: anArray

Rezultatem wykonania bloku kodu jest obiekt zwracany przez ostatnie wyrażenie wykonane w tym bloku. Pusty blok zwraca jako wynik swojego wykonania nil.

[] value. "Zwraca nil"

[2] value. "Zwraca 2"

[|x y z|
   x := 2.
   y := 4.
   z := x + y.
   x + z] value. "Zwraca 8 (rezultat wykonania x + z)"

[:arg1 :arg2 | arg1 + arg2] value: 22 value: 6. "Zwraca 28"

[:a :b :c :d :e | a * b - c + d - e] valueWithArguments: #(7 4 9 2 1). "Zwraca 20"

Bloki kodu są najczęściej wykorzystywane jako argumenty metod:

(a > b)
   ifTrue: [doSomething].

[counter > 10] whileFalse:[
   doSomething. counter := counter + 1].
"Tutaj także jako odbiorca wiadomości"

aCollection do: [:eachElement |
   eachElement doSomething]
.

aCollection select: [:eachElement |
   eachElement = anObject]
.

1 to: 10 do: [:index |
   (anArray at: index) doSomething]
.

 

  • Java

Java nie oferuje mechanizmu bloków kodu. Ze względu na ograniczoną obiektowość Javy nie miałyby one też większego zastosowania (pętle, struktury kontrolne itp. są zrealizowane w Javie w sposób nieobiektowy)





SelfSmaltalk, (c) ObjectSpace.Net
Strona wygenerowana przy pomocy edytora aceHTML
i systemu VisualWorks Smalltalk NC 7.0