Java a język C

Java i C++

Jedną z przyczyn szybkiej akceptacji Javy jest z pewnością jej podobieństwo do C++. Ma to niebagatelne znaczenie, ponieważ większość współczesnych programistów zna C++ dość dobrze, a potwierdzeniem tego może być mało znana wiadomość, że opracowane w USA Informatyczne Testy Kwalifikacyjne dla uczniów szkół średnich (oryg. Advanced Placement Tests) zakładają znajomość C++ (chociaż nikogo zapewne nie zdziwi, jeśli w najbliższej przyszłości zostaną zastąpione testami z Javy).

Z podstawowego C++ zapożyczono do Javy większość składni. Zrezygnowano jedynie z dyrektyw, struktur, unii, wskaźników, operatorów definiowanych i wielodziedziczenia (oryg. multiple inheritance).

Jako rekompensatę zapewniono przenośność programów między dowolnymi platformami sprzętowymi i systemowymi, zdalne wywoływanie metod (funkcji składowych klas), wbudowano w język mechanizmy współbieżności i dynamicznego zarządzania pamięcią oraz uniemożliwiono wyrządzanie szkód przez aplety pochodzące z niepewnych źródeł.

Zwłaszcza ta ostatnia cecha (której poświęcono ulubione przez większość "prawdziwych" programistów wskaźniki) zadecyduje zapewne o przyszłości Javy jako języka Internetu. Istnieje bowiem gwarancja, że nikt nie poniesie uszczerbku, jeśli z ciekawości lub z potrzeby skorzysta z dowolnego apletu, który znajdzie w Internecie, w tym z takiego, który został napisany przez złośliwego programistę.

Dzięki wprowadzonym uproszczeniom, nie występują w Javie takie znane z C++ deklaracje jak na przykład

void (*signal(int, void (*)(int)))(int);

które nawet wprawnym programistom sprawiają od czasu do czasu trudności.

Na skutek dołączenia do języka obszernych bibliotek, programy napisane w Javie są dość krótkie i dużo bardziej przejrzyste niż analogiczne programy napisane w C++. Dzięki temu uruchamianie i testowanie programów staje się łatwiejsze, a kod źródłowy ma cechy samodokumentujące (oryg. self-documenting).

Wszystkie to razem powoduje, że popularność Javy stale rośnie i coraz to nowe rzesze użytkowników przekonują się do tego języka. Szczególnie widoczne jest to w znanych środowiskach akademickich, gdzie z planów dydaktycznych są na korzyść Javy eliminowane takie popularne języki programowania jak Visual Basic, Delphi i Turbo Pascal.

Java a język C++

U podstaw zrozumienia Javy leży pojęcie odnośnika (zmiennej do identyfikowania innych zmiennych) oraz odniesienia (danej identyfikującej zmienną, przypisywanej odnośnikowi).

Ponieważ odnośniki istnieją w C++, można je przypomnieć odwołując się do następującego programu (którego zresztą, jako jednego z nielicznych, nie da się zapisać w Javie).

#include <iostream.h>

int main(void)

{

int one = 10, two = 20;

int &max(int &, int &);

cout << max(one, two) << endl; // 20

return 0;

}

int &max(int &refOne, int &refTwo)

{

return refOne > refTwo ? refOne : refTwo;

}

W chwili wywołania funkcji max odnośnik refOne jest inicjowany odniesieniem do zmiennej one, a odnośnik refTwo jest inicjowany odniesieniem do zmiennej two.

Rezultatem funkcji max jest odnośnik typu "int &" zainicjowany odniesieniem do większego z argumentów.

Klasy

Podobnie jak w C++, klasa jest opisem rodziny obiektów. Struktura obiektów jest określona przez pola klasy, a operacje na obiektach są określone przez jej konstruktory i metody.

Poza polami, konstruktorami i metodami klasa może zawierać także zmienne i funkcje statyczne. Takie składniki klasy (oryg. members) nie są związane z poszczególnymi obiektami, ale należą do całej klasy.

Istotna z punktu widzenia ochrony informacji dostępność (oryg. acessibility) pól, metod, zmiennych i funkcji jest w Javie określana indywidualnie, a nie tak jak w C++, w ramach sekcji. Jeśli dostępności pewnych składników klasy nie określi się jawnie, to będą one dostępne w pakiecie klas. Stanowi to odmianę deklaracji zaprzyjaźnienia (oryg. friend) znanej z C++.

public

class Complex { // publiczna klasa

protected double re; // chronione pole

private double im; // prywatne pole

public Complex

(double re, double im) // publiczny konstruktor

{

this.re = re;

this.im = im;

}

double abs() // przyjazna metoda

{

return Math.sqrt(re * re + im * im);

}

}

Ponieważ w Javie nie ma list inicjacyjnych, więc inicjowanie pól obiektu odbywa się w ciele konstruktora.

Zmienne

Deklaracje zmiennych typów predefiniowanych (w tym "char", "int", "long", "boolean") mają w Javie taką samą interpretację jak w ANSI C++.

Zmienne typu "char" są 16-bitowe, dzięki czemu umożliwiają reprezentowanie wszystkich znaków Unikodu (oryg. Unicode).

W szczególności

int var = 12

jest deklaracją zmiennej var typu "int" zainicjowanej daną o wartości 12, a

char chr = 'ś'

jest deklaracją zmiennej chr zainicjowaną kodem litery ś.

Natomiast deklaracje, w których występuje typ definiowany są interpretowane inaczej niż w C++.

Na przykład

class Point {

// ...

}

Point point;

Zadeklarowano odnośnik point do zmiennych klasy Point, a nie obiekt point klasy Point.

Obiekty

Ponieważ w Javie nie ma struktur ani unii, więc każdy jej obiekt jest egzemplarzem pewnej klasy (oryg. class instance). Z klasą są związane jej zmienne i funkcje, a w obiektach są zawarte zmienne, konstruktory i metody.

Właściwości zmiennych klasy, zarówno tych które są wspólne jej wszystkim obiektom, jak i tych, które wchodzą w skład poszczególnych obiektów, są określone przez deklaracje pól klasy (oryg. class field).

Uwaga: Ze względu na efektywność implementacji, kod metod klasy nie jest powielany i znajduje się fizycznie (ale nie logicznie!) poza obiektami klasy.

W następującej definicji klasy sklasyfikowano jej składniki.

class Fixed {

static int count = 0; // zmienna

static int getCount() // funkcja

{

return count;

}

int value; // pole

Fixed(int val) // konstruktor

{

value = val;

count++;

}

int getValue() // metoda

{

return value;

}

}

Fabrykowanie obiektów

W celu utworzenia obiektu należy użyć wyrażenia fabrykującego (oryg. factory expression) o postaci

new TypObiektowy(Arg, Arg, ... , Arg)

Jego rezultatem jest odnośnik zawierający odniesienie do właśnie sfabrykowanej zmiennej (w Javie słowo kluczowe new nie jest operatorem!).

public void paint(Graphics gDC)

{

Point point;

point = new Point(10, 20);

gDC.drawLine(0, 0, point.x, point.y);

}

Odniesienie do obiektu sfabrykowanego podczas opracowania wyrażenia

new Point(10, 10)

przypisano odnośnikowi point.

Uwaga: W odróżnieniu od C++, w Javie nie można za pomocą operacji new, tworzyć zmiennych skalarnych nie-obiektowych. A zatem nie istnieją wyrażenia fabrykujące takie jak na przykład

new int

albo

new Point

Odnośniki a wskaźniki

Reakcją każdego kto dowiaduje się, że w Javie nie ma wskaźników jest pytanie:

A jak programuje się listowe struktury danych?

Bo przecież w C++ bez wskaźników nie ma na to sposobu.

Okazuje się jednak, że odnośniki można w Javie nie tylko inicjować, ale że można im także przypisywać odniesienia. To już rozwiązuje problem.

W szczególności następujący program w C++

include <iostream.h>

struct Item {

Item *next;

int value;

Item(int i) : value(i)

{

}

};

int main(void)

{

Item *head = 0;

for(int i = 0; i < 10 ; i++) {

Item *newItem = new Item(i);

newItem->next = head;

head = newItem;

}

// ...

return 0;

}

przybiera w Javie postać

class Item {

Item next;

int value;

Item(int i)

{

value = i;

}

}

public

class Main {

public static void main(String args[])

{

Item head = null;

for(int i = 0; i < 10 ; i++) {

Item newItem = new Item(i);

newItem.next = head;

head = newItem;

}

// ...

}

}

A zatem brak wskaźników w Javie nie stanowi żadnego ograniczenia w możliwościach programowania dynamicznych struktur danych.

Między bajki można także włożyć opowieści o tym dla jakich to wzniosłych celów poświęcono wskaźniki. W istocie bezpieczeństwo Javy i wykluczenie możliwości programowania w niej wirusów, nie wynika z pozbycia się wskaźników, ale z wyeliminowania konwersji wskaźnikowych oraz z rygorystycznej kontroli ładowania i interpretowania B-kodu.

Procedury

Procedurami są konstruktory, funkcje i metody klasy (w Javie nie ma funkcji i zmiennych globalnych!). Identycznie jak w C++, każda procedura znajduje się w zakresie (oryg. scope) jej klas macierzystych, a zatem z ciała procedury są dostępne wszystkie składniki klasy, w tym również te, których deklaracje występują poniżej definicji procedury.

Na przykład

class Master {

int dx()

{

return dx;

}

int dx = 0;

// ...

}

Zasługuje na uwagę, że w Javie wolno definiować pole i metodę o takim samym identyfikatorze.

Zmienne lokalne

Zakresem i jednocześnie zasięgiem deklaracji zmiennej lokalnej (w tym parametru) procedury jest cały blok w którym wystąpiła deklaracja (począwszy od punktu tuż za deklaratorem).

Zasięgiem deklaracji zmiennych sterujących instrukcji for jest tylko ciało tej instrukcji.

void Sub(int x, int y)

{

for(int i = 0; false ; );

for(int i = 1; false ; ); // dobrze (w ANSI C++ błąd!)

int v = i; // błąd (nieznany inicjator)

int j = 2;

for(int j = 2; false ; ); // błąd (ponowna deklaracja)

int y; // błąd (ponowna deklaracja)

int z = 10;

int v = 20;

{

int v = 30; // błąd (ponowna deklaracja)

int u = 40;

}

{

int u = 50; // dobrze!

int z = 60; // błąd (ponowna deklaracja)

}

}

Odnośnik this

W ciele konstruktora i metody jest dostępny odnośnik this identyfikujący obiekt na rzecz którego wywołano konstruktor albo metodę.

Pierwszą (i tylko pierwszą!) instrukcją konstruktora może być instrukcja

this(Arg, Arg, ... , Arg);

albo

super(Arg, Arg, ... , Arg);

W pierwszej z nich jest wywoływany konstruktor danej klasy, a w drugiej konstruktor jej nadklasy (klasy bazowej). Jeśli w ciele konstruktora nie wystąpi żadna z tych instrukcji, to domniema się, że jego pierwszą instrukcją jest

super();

Dziedziczenie

Dziedziczenie wyraża się za pomocą słowa kluczowego extends.

Ponieważ istnieje tylko jedna klasa pierwotna (jest nią Object), więc w Javie hierarchia klas jest drzewem, a nie lasem (grafem acyklicznym) jak w C++.

class MyObject extends Object {

// ...

}

Polimorfizm

Każda metoda Javy jest domyślnie wirtualna (oryg. virtual). Każde wywołanie metody, która nie jest prywatna jest polimorficzne, tj.

Do wykonania jest wybierana metoda identyfikowana przez odniesienie przypisane odnośnikowi na rzecz którego odbywa się wywołanie.

Uwaga: Podczas kompilowania programu typ odnośnika służy tylko do upewnienia się, że w jego klasie (albo w interfejsie) występuje definicja wywoływanej metody. Podczas wykonywania programu typ odnośnika nie jest już brany pod uwagę.

class Horse {

// ...

void draw(Graphics gDC)

{

// ... wykreśl konia

}

static void fun(Graphics gDC, Horse horse)

{

horse.draw(gDC);

}

}

class Zebra extends Horse {

// ...

void draw(Graphics gDC)

{

// ... wykreśl zebrę

}

}

Wywołanie

horse.draw(gDC)

jest polimorficzne.

Jeśli parametr horse identyfikuje obiekt klasy Zebra, na przykład po wywołaniu funkcji fun z procedury paint

public void paint(Graphics gDC)

{

fun(gDC, new Zebra("Stripes", 8));

}

to w funkcji fun zostanie wywołana metoda draw klasy Zebra, mimo iż horse jest odnośnikiem do obiektów klasy Horse.

Implementowanie

Mimo iż każda klasa może mieć co najwyżej jedną nadklasę (w Javie nie ma wielodziedziczenia!), to jednak może implementować dowolnie wiele interfejsów.

Uwaga: Interfejs jest odmianą klasy abstrakcyjnej, która zawiera tylko deklaracje metod i definicje zmiennych.

Jeśli klasa implementuje interfejs, a nie ma być klasą abstrakcyjną, to musi dostarczyć definicje wszystkich metod zadeklarowanych w interfejsie.

Uwaga: Implementowanie interfejsu stosuje się najczęściej wówczas, gdy zestaw klas ma bardzo odległego, albo niedostępnego przodka, ale gdy musi być wyposażony we wspólną cechę, wyrażaną takimi słowami jak: skalowalna, przemieszczalna, przeliczalna, wykonywalna, itp.

class Shape {

// ...

}

interface Drawable {

// ...

void draw(Graphics gDC);

}

class DrawableShape extends Shape implements Drawable {

// ...

DrawableShape()

{

}

public void draw(Graphics gDC)

{

// ...

}

}

Wywoływanie

Każdemu odnośnikowi typu interfejsowego można przypisać odniesienie do obiektu klasy implementującej ten interfejs. Na rzecz takiego odnośnika można wówczas wywołać dowolną metodę tej klasy. Wywołanie takie jest wówczas polimorficzne.

Na przykład

public void paint(Graphics gDC)

{

Drawable item = new DrawableShape();

item.draw(gDC);

}

Wywołanie

item.draw(gDC);

jest polimorficzne.

Mimo iż odnośnik item jest klasy Drawable, następuje wywołanie metody draw klasy DrawableShape.

Tablice

Deklaracja tablicy w Javie jest deklaracją odnośnika do tablicy. Sama tablica musi być utworzona za pomocą wyrażenia fabrykującego.

Uwaga: Każda tablica jest obiektem klasy pochodnej klasy Object i implementuje interfejs Cloneable. Obiekt tablicowy jest wyposażony w publiczne pole length określające liczbę elementów tablicy.

Elementy predefiniowane

W celu utworzenia tablicy o elementach typu predefiniowanego należy użyć wyrażenia fabrykującego

new Typ [Rozmiar]

Jego rezultatem jest anonimowy odnośnik zainicjowany odniesieniem do właśnie sfabrykowanej tablicy.

Na przykład, wykonanie instrukcji

int arr[]; // deklaracja odnośnika

arr = new int [3]; // utworzenie tablicy

for(int i = 0; i < arr.length ; i++)

arr[i] = 0;

powoduje utworzenie i zainicjowanie (liczbą 0) wszystkich elementów tablicy identyfikowanej przez odnośnik arr.

Elementy obiektowe

W celu utworzenia tablicy o elementach typu obiektowego należy użyć wyrażenia fabrykującego

new Typ [Rozmiar]

Jego rezultatem jest odnośnik zainicjowany odniesieniem do wektora odnośników do elementów właśnie sfabrykowanej tablicy.

Na przykład, wykonanie instrukcji

String arr[]; // deklaracja odnośnika

arr = new String [3]; // utworzenie wektora odnośników

for(int i = 0; i < arr.length ; i++)

arr[i] = new String(); // utworzenie elementu podstawowego

powoduje utworzenie i zainicjowanie (pustym łańcuchem) wszystkich elementów podstawowych tablicy identyfikowanej przez odnośnik arr.

Wyjątki

Jeśli wykonanie instrukcji może spowodować powstanie sytuacji wyjątkowej nie wywodzącej się od RuntimeException i Error, to taka instrukcja musi być ujęta w blok instrukcji try, albo nagłówek procedury obejmującej tę instrukcję musi zawierać frazę throws wyszczególniającą klasę wyjątku.

W pierwszym przypadku we frazie catch określa się co należy uczynić w razie powstania sytuacji wyjątkowej, a w drugim pozostawia się taką decyzję procedurze wywołującej.

Na przykład, podczas wykonywania procedury

void setChar(char arr[], int pos, FileInputStream src)

{

int chr = src.read(); // IOException

arr[pos] = chr; // IndexOutOfBoundsException

}

mogą powstać dwie sytuacje wyjątkowe: IOException związana z nieudaną operacją wejścia oraz IndexOutOfBoundsException (klasy pochodnej od RuntimeException) związana z niewłaściwie dobranym indeksem tablicy.

Pierwsza z nich wymaga ujęcia instrukcji

int chr = src.read(); // IOException

w blok instrukcji try, na przykład

void setChar(char arr[], int pos, FileInputStream src)

{

try {

int chr = src.read(); // IOException

}

catch(IOException e) {

// ... // reakcja na sytuację wyjątkowa

}

arr[pos] = chr; // IndexOutOfBoundsException

}

albo użycia frazy throws wyszczególniającej klasę IOException

void setChar(char arr[], int pos, FileInputStream src)

throws IOException

{

int chr = src.read(); // IOException

arr[pos] = chr; // IndexOutOfBoundsException

}

natomiast druga nie wymaga takich zabiegów.

Uwaga: Jeśli użyto frazy throws, to instrukcja wywołująca procedurę setChar musi być ujęta w blok instrukcji try, albo procedura zawierająca taką instrukcję musi zawierać frazę throws wyszczególniającą klasę IOException.


Wyszukiwarka

Podobne podstrony:
05 WeWy, wisisz, wydzial informatyki, studia zaoczne inzynierskie, jezyk java
04 Funkcje, wisisz, wydzial informatyki, studia zaoczne inzynierskie, jezyk java
03 Instrukcje, wisisz, wydzial informatyki, studia zaoczne inzynierskie, jezyk java
08 Zdarzenia, wisisz, wydzial informatyki, studia zaoczne inzynierskie, jezyk java
Jezyk Java
Język jako narzędzie paradoksy
Język w zachowaniach społecznych, Wykład na I roku Kulturoznawstwa (1)
Java Media FreamWork
Język haseł przedmiotowych2
Laboratorium jezyk c4 2013
java 2
motywy literackie matura 2016 język polski
Projekt java
JAVA tablice
Jezyk polski 5 Ortografia Zas strony 48 49 id 222219

więcej podobnych podstron