Typy definiowane przez programistę
Definiowanie nowych typów danych przez programistę możliwe jest na drodze definiowania szablonów opisujących strukturę danych oraz
zestawu operacji możliwych do wykonania na danych nowego typu.
Szablon definiujący nowy typ nazywany jest klasą.
Struktura danych opisywana jest za pomocą pól, natomiast zestaw operacji możliwych do wykonania za pomocą metod.
Pola przechowują informacje charakterystyczne dla całej klasy lub dla pojedynczego egzemplaza klasy.
Metody zazwyczaj opisują sposób przetwarzania pól klasy.
Definicja typowej klasy umieszczana jest w pliku o nazwie zgodnej z nazwą klasy i posiadającym rozszerzenie . java.
Podstawy programowania
Materiały do użytku wewnętrznego
6.1
Definicja klasy (1/2)
Definicja klasy tworzona jest za pomocą słowa kluczowego class i może wyglądać jak poniżej:
modyfikator class NazwaKlasy
{
modyfikator typ nazwaPola_1;
.
.
.
modyfikator typ nazwaPola_N;
modyfikator typ nazwaMetody_1( definicja_parametrów ) {
treść_metody
}
.
.
.
modyfikator typ nazwaMetody_N( definicja_parametrów ) {
treść_metody
}
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.2
Definicja klasy (2/2)
Przykład 1
class Punkt
{ }
Przykład 2
class Punkt
{
double x;
double y;
}
Przykład 3
public class Punkt
{
private double x;
private double y;
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.3
Tworzenie obiektu (1/2)
Dysponując definicją klasy (szablonem), można utworzyć obiekty, będące
jej egzemplarzami.
Zmienne wskazujące na egzemplarze klasy (obiekty) nazywane są
zmiennymi obiektowymi.
Zmienna obiektowa przechowuje adres (referencję) do obszaru pamięci RAM komputera, w którym składowane są elementy obiektu.
Tworzenie obiektu polega na przydzieleniu obszaru w pamięci RAM i przypisaniu jego adresu do zmiennej obiektowej. Wielkość przydzielanego obszaru zależy od klasy tworzonego obiektu.
Próba odwołania się do elementów obiektu przed jego utworzeniem powoduje błąd wykonania programu.
Podstawy programowania
Materiały do użytku wewnętrznego
6.4
Tworzenie obiektu (2/2)
Jednym ze sposobów utworzenia obiektu jest wykorzystanie operatora
new.
nazwa_klasy zmienna_obiektowa = new nazwa_klasy();
lub
nazwa_klasy zmienna_obiektowa;
zmienna_ obiektowa = new nazwa_klasy();
Przykład 1
class Punkt
{
double x;
double y;
}
Punkt punktA = new Punkt();
Punkt punktB;
punktB = new Punkt();
Podstawy programowania
Materiały do użytku wewnętrznego
6.5
Konstruktory (1/4)
Wartościami domyślnymi pól obiektu są wartości 0 (dla typów numerycznych) oraz false (dla typu boolean). Dla typu char jest to znak
'\u0000'.
Tworzenie obiektu można połączyć z operacją inicjowania wartości jego pól. Wykorzystuje się do tego celu specjalny rodzaj metod zwanych konstruktorami.
Konstruktor jest uruchamiany automatycznie podczas tworzenia obiektu.
Jeżeli w klasie nie zdefiniowano żadnego konstruktora, uruchamiany jest tzw. konstruktor domyślny.
Gdy konstruktor zdefiniowany w klasie posiada parametry, podczas tworzenia obiektu należy przekazać doń odpowiednie argumenty:
nazwa_klasy zmienna_obiektowa = new nazwa_klasy( argumenty ); Podstawy programowania
Materiały do użytku wewnętrznego
6.6
Konstruktory (2/4)
Definicja konstruktora wygląda następująco:
NazwaKlasy ()
{
treść_konstruktora
}
lub
NazwaKlasy ( definicja_parametrów )
{
treść_konstruktora
}
Z kolei definicja parametrów:
typ nazwa_parametru_1, … typ nazwa_parametru_n
Podstawy programowania
Materiały do użytku wewnętrznego
6.7
Konstruktory (3/4)
Przykład – konstruktor bez parametrów
class Punkt
{
double x;
double y;
Punkt()
{
x = 0.0;
y = 0.0;
}
}
Punkt pA = new Punkt();
Podstawy programowania
Materiały do użytku wewnętrznego
6.8
Konstruktory (4/4)
Przykład – konstruktor z parametrami
class Punkt
{
double x;
double y;
Punkt( double nX, double nY )
{
x = nX;
y = nY;
}
}
Punkt pA = new Punkt( 2.0, 4.0 );
Podstawy programowania
Materiały do użytku wewnętrznego
6.9
Przeciążanie konstruktorów (1/3)
Możliwe jest zdefinowanie wielu konstruktorów w jednej klasie pod warunkiem posiadania przez nie innego zestawu parametrów.
Konstruktory rozróżniane są wyłącznie na podstawie liczby i typów zdefiniowanych parametrów.
Wywołanie konstruktora powinno odbyć się z takim zestawem
argumentów, które umożliwią dopasowanie właściwego konstruktora
spośród wielu zdefinowanych w klasie.
Konstruktory nie są rozróżniane na podstawie nazw parametrów – nie jest możliwe zdefiniowanie dwóch konstruktorów o tym samym zestawie typów
parametrów i różnych nazwach.
Podstawy programowania
Materiały do użytku wewnętrznego
6.10
Przeciążanie konstruktorów (2/3)
class Punkt
{
double x;
double y;
Punkt()
{
x = 0.0; y = 0.0;
}
Punkt( double nX, double nY )
{
x = nX; y = nY;
}
}
Punkt pA = new Punkt();
Punkt pB = new Punkt( 2.0, 4.0 );
Punkt pC = new Punkt( 2.0 ); //BŁĄD!!!
Podstawy programowania
Materiały do użytku wewnętrznego
6.11
Przeciążanie konstruktorów (3/3)
Możliwe jest jawne uruchomienie konstruktora – w tym celu należy posłużyć się słowem kluczowym this:
class Punkt
{
double x;
double y;
Punkt()
{
this( 0.0, 0.0 );
}
Punkt( double nX, double nY )
{
x = nX; y = nY;
}
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.12
Destruktory
Funkcję przeciwną do konstruktora pełni destruktor, wywoływany
automatycznie tuż przed zwolnieniem pamięci przydzielonej obiektowi.
Definicja destruktora wygląda jak poniżej:
... public void finalize()
...{
//treść_destruktora
...}
Za wykonanie operacji zwalniania pamięci odpowiada specjalizowany moduł wirtualnej maszyny Javy (ang. garbage collector).
Pamięć przydzielona obiektowi zwalniana jest wtedy, gdy w programie nie będzie referencji do obszaru pamięci przydzielonemu obiektowi.
Podstawy programowania
Materiały do użytku wewnętrznego
6.13
Dostęp do pól obiektu (1/5)
Dostęp do pól obiektu możliwy jest za pomocą operatora selekcji - .
(kropka), np.:
nazwa_klasy zmienna_obiektowa = new nazwa_klasy();
zmienna_obiektowa.nazwa_pola = wyrażenie;
Podstawy programowania
Materiały do użytku wewnętrznego
6.14
Dostęp do pól obiektu (2/5)
class Punkt
{
double x;
double y;
Punkt()
{
x = 0.0; y = 0.0;
}
Punkt( double nX, double nY )
{
x = nX; y = nY;
}
}
Punkt pA = new Punkt();
pA.x = 10.0;
pA.y = 5.0;
Podstawy programowania
Materiały do użytku wewnętrznego
6.15
Dostęp do pól obiektu (3/5)
W szczególnych przypadkach dostęp do pól obiektu można uzyskać w ciele konstruktora lub metody za pomocą słowa kluczowego this.
Ilustruje to poniższy przykład:
class Punkt
{
double x;
double y;
Punkt()
{
x = 0.0; y = 0.0;
}
Punkt( double x, double y )
{
this.x = x; this.y = y;
}
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.16
Dostęp do pól obiektu (4/5)
Definicja pola klasy, konstruktora lub metody może być poprzedzona tzw.
modyfikatorem dostępu, określającym „widoczność” pola dla różnych części kodu tworzącego program.
Dopuszczalne jest użycie poniższych modyfikatorów: public, private, protected.
Klasa
Modyfikator
Klasa
Pakiet
Świat
pochodna
public
T
T
T
T
protected
T
T
T
N
brak
T
T
N
N
private
T
N
N
N
Pakiet – grupa klas o podobnej funkcjonalności, np. pakiet klas obliczeń numerycznych.
Podstawy programowania
Materiały do użytku wewnętrznego
6.17
Dostęp do pól obiektu (5/5)
class Punkt
{
private double x;
private double y;
Punkt()
{
x = 0.0; y = 0.0;
}
Punkt( double nX, double nY )
{
x = nX; y = nY;
}
}
Punkt pA = new Punkt();
pA.x = 10.0; //BŁĄD!
pA.y = 5.0; //BŁĄD!
Podstawy programowania
Materiały do użytku wewnętrznego
6.18
Pola statyczne (wspólne) (1/2)
Użycie w definicji pola klasy modyfikatora static powoduje, że pole jest dostępne dla każdego obiektu tej klasy. Inaczej mówiąc, pole jest wspólne dla wszystkich obiektów danej klasy.
Pamięć dla takiego pola zostaje przydzielona podczas inicjowania klasy –
pole istnieje nawet wtedy, gdy nie istnieje żaden obiekt danej klasy.
Dostęp do pola możliwy jest za pomocą operatora selekcji oraz nazwy klasy lub zmiennej obiektowej.
Podstawy programowania
Materiały do użytku wewnętrznego
6.19
Pola statyczne (wspólne) (2/2)
class Punkt
{
static finale double PI = 3.14159265;
private double x;
private double y;
Punkt()
{
x = 0.0; y = 0.0;
}
}
System. out.println( Punkt. PI );
Punkt pA = new Punkt();
System. out.println( pA. PI );
Podstawy programowania
Materiały do użytku wewnętrznego
6.20
Metody (1/3)
Definicja metody wygląda jak poniżej:
modyfikator typ nazwaMetody ( definicja_parametrów )
{
treść_metody
}
modyfikator - określa (podobnie jak dla pól) zakres dostępu do metody w różnych fragmentach kodu tworzącego program.
typ – typ wartości obliczanej przez metodę, np. double, int, String.
definicja_parametrow – lista parametrów metody (może być pusta) w postaci: typ nazwa_parametru.
treść
metody
–
instrukcje
języka
Java
realizujące
algorytm
przetwarzania.
Podstawy programowania
Materiały do użytku wewnętrznego
6.21
Metody (2/3)
class Punkt
{
double x;
double y;
Punkt()
{
x = 0.0; y = 0.0;
}
public double odleglosc()
{
return Math. sqrt( x*x + y*y );
}
public void przesun( double deltaX, double deltaY )
{
x += deltaX; y += deltaY;
}
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.22
Metody (3/3)
Punkt pA = new Punkt();
pA.x = 4.0;
pA.y = 5.0;
System. out.println( pA.odleglosc() ); // 0.0
pA.przesun( 3.0, 4.0 );
System. out.println( pA.odleglosc() ); // 5.0
Podstawy programowania
Materiały do użytku wewnętrznego
6.23
Metody – przeciążanie (1/3)
Podobnie jak w przypadku konstruktorów, możliwe jest zdefinowanie w klasie wielu metod o takiej samej nazwie i różniących się typem obliczanej wartości oraz definicją parametrów.
Metody rozróżniane są wyłącznie na podstawie nazwy oraz liczby i typów
zdefiniowanych parametrów.
Metody nie są rozróżniane na podstawie nazw parametrów – nie jest możliwe zdefiniowanie dwóch metod o tym samym zestawie typów
parametrów i różnych nazwach parametrów.
Metody nie są również rozróżniane na podstawie typów zwracanej
wartości.
Wywołanie metody powinno odbyć się z takim zestawem argumentów, które umożliwią dopasowanie właściwej metody spośród wielu
zdefinowanych w klasie.
Podstawy programowania
Materiały do użytku wewnętrznego
6.24
Metody – przeciążanie (2/3)
class Punkt
{
double x;
double y;
Punkt()
{
x = 0.0; y = 0.0;
}
public double odleglosc()
{
return Math. sqrt( x*x + y*y );
}
public double odleglosc( Punkt p )
{
double dx = x - p.X();
double dy = y - p.Y();
return Math.sqrt( dx*dx + dy*dy );
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.25
Metody – przeciążanie (3/3)
Punkt pA = new Punkt();
Punkt pB = new Punkt();
pA.x = 3.0;
pA.y = 4.0;
pB.x = -3.0;
pB.y = -4.0;
System. out.println( pA.odleglosc() ); // 5.0
System. out.println( pA.odleglosc( pB ) ); // 10.0
Podstawy programowania
Materiały do użytku wewnętrznego
6.26
Metody statyczne (1/3)
Użycie w definicji metody klasy modyfikatora static powoduje, że kod metody ma dostęp wyłącznie do statycznych komponentów klasy.
Dostęp do metody statycznej (np. w celu jej uruchomienia) można uzyskać za pomocą operatora selekcji (. – kropka) oraz nazwy klasy lub zmiennej obiektowej.
Podstawy programowania
Materiały do użytku wewnętrznego
6.27
Metody statyczne (2/3)
class Punkt {
double x;
double y;
public double odleglosc()
{
return Math. sqrt( x*x + y*y );
}
public static double odleglosc( Punkt pA, Punkt pB )
{
double dx = pA.gX() - pB.gX();
double dy = pA.gY() - pB.gY();
return Math.sqrt( dx*dx + dy*dy );
}
public static double odleglosc( double xA, double yA, double xB, double yB)
{
double dx = xA - xB;
double dy = yA - yB;
return Math.sqrt( Math.pow( dx, 2 ) + Math.pow( dy, 2 ) );
}
System. out.println( Punkt.odleglosc( 3.0, 4.0, -3.0, -4.0 ) ); // 10.0
Podstawy programowania
Materiały do użytku wewnętrznego
6.28
Metody statyczne (3/3)
Na szczególną uwagę zasługuje statyczna metoda main, której parametrami jest tablica wartości typy String zawierająca argumenty uruchomienia programu (podane np. w wierszu poleceń).
Od tej właśnie metody rozpoczyna się wykonywanie programu w języku JAVA.
public class Obliczenia
{
public static void main( String[] args )
{
int arg1 = Integer. parseInt( args[ 0 ] );
int arg2 = Integer. parseInt( args[ 1 ] );
System. out.println( "Suma: " + (arg1 + arg2) );
}
}
java Obliczenia 2 3
Podstawy programowania
Materiały do użytku wewnętrznego
6.29
Metody – przekazywanie argumentów (1/4)
Użyteczność metod wynika m.in. z ich parametryzacji, np. biblioteczna metoda Math.sin obliczająca wartość funkcji sinus jest użyteczna, ponieważ można ją uruchomić, podając wartość argumentu, dla którego ma zostać wykonana.
W języku Java podczas wywoływania sparametryzowanych metod
zawsze przekazywane są wartości argumentów.
W przypadku argumentów będących obiektami, wartości te zawierają referencje (odwołania) do obszaru pamięci przydzielonego obiektowi.
Metoda nie może zmienić wartości argumentów, które zostały przekazane jej w chwili uruchomienia.
W języku Java nie istnieje pojęcie przekazywania argumentów przez referencję.
Podstawy programowania
Materiały do użytku wewnętrznego
6.30
Metody – przekazywanie argumentów (2/4)
Przykład
Przykład
int a = 1;
Integer a = 1;
oblicz( a );
oblicz( a );
System. out.println( "a=" + a );
System. out.println( "a=" + a );
//a=1
//a=1
void oblicz( int pA )
void oblicz( Integer pA )
{
{
pA *= 2;
pA *= 2;
}
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.31
Metody – przekazywanie argumentów (3/4)
Przykład
LiczbaCalkowita c = new LiczbaCalkowita( 1 );
oblicz( c );
System. out.println( "c=" + c.liczba ); //c=2
void oblicz( LiczbaCalkowita pA )
{
pA.liczba *= 2;
}
public class LiczbaCalkowita
{
int liczba;
LiczbaCalkowita( int pLiczba )
{
liczba = pLiczba;
}
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.32
Metody – przekazywanie argumentów (4/4)
Przykład
int [] b = { 1, 2 };
oblicz( b );
for( int k = 0; k < b.length; k++ )
System. out.println( "b[" + k + "]=" + b[k] );
//b[0]=2
//b[1]=4
void oblicz( int [] pA )
{
for( int k = 0; k < pA.length; k++ ) pA[ k ] *= 2;
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.33
Metody – zwracanie wyników (1/2)
Wartości obliczane zwracane są do miejsca wywołania metody za
pomocą instrukcji return.
W przypadku typów prostych jest to wartość odpowiedniego typu
(wynikającego z definicjiii metody).
W przypadku obiektów (tablice też są obiektami) jest to wartość referencji do obszaru pamięci przydzielonego obiektowi (np. tablicy).
Podstawy programowania
Materiały do użytku wewnętrznego
6.34
Metody – zwracanie wyników (2/2)
Przykład 1
public static Punkt zrobPunkt( double aX, double aY )
{
return new Punkt( aX, aY );
}
Punkt pA = zrobPunkt( 2.0, 4.0 );
Przykład 2
public static Punkt [] zrobTablice( int aN )
{
Punkt [] tablica = new Punkt[ aN ];
for( int k = 0; k < aN; k++ ) tablica[ k ] = new Punkt(); return tablica;
}
Punkt [] tpA = zrobTablice ( 4 );
Podstawy programowania
Materiały do użytku wewnętrznego
6.35
Metody – rekurencja (1/4)
Metoda rekurencyjna to metoda, która wywołuje samą siebie (zwykle dla innych wartości argumentów).
Przykładem zastosowania metod rekurencyjnych jest obliczanie funkcji silnia lub wyrazów ciagu Fibonacciego.
Przykład – silnia
public int silnia( int p )
{
if ( p == 1 ) return 1; else return silnia( p-1 ) * p;
}
System. out.println( silnia( 5 ) ); // 120
System. out.println( silnia( 1 ) ); // 1
Podstawy programowania
Materiały do użytku wewnętrznego
6.36
Metody – rekurencja (2/4)
Przykład – Fibonacci
public int fibonacci( int p )
{
if ( p == 1 ) return 0;
if ( p == 2 ) return 1;
return fibonacci( p - 2 ) + fibonacci( p - 1 );
}
System. out.println( fibonacci( 1 ) ); // 0
System. out.println( fibonacci( 2 ) ); // 1
System. out.println( fibonacci( 5 ) ); // 3
Podstawy programowania
Materiały do użytku wewnętrznego
6.37
Metody – rekurencja (3/4)
Przykład - sortowanie szybkie - metoda
public void sortowanie( int t [], int d, int g )
{
int m = d;
int n = g;
int s = t [ ( d + g ) / 2 ];
do
{
while ( t[ m ] < s ) m++;
while ( s < t[ n ] ) n--;
if ( m <= n )
{
int tmp = t[ m ];
t[ m ] = t[ n ];
t[ n ] = tmp;
m++; n--;
}
}
while ( m <= n );
if ( d < n ) sortowanie( t, d, n );
if ( m < g ) sortowanie( t, m, g);
}
Podstawy programowania
Materiały do użytku wewnętrznego
6.38
Metody – rekurencja (4/4)
Przykład - sortowanie szybkie - zastosowanie
int [] punkty = { 70, 43, 74, 2, 29, 10, 82, 92, 2, 17 };
sortowanie( punkty, 0, punkty.length-1 );
for( int k = 0; k < punkty.length; k++ )
System. out.print(punkty[ k ] + " " );
//2 2 10 17 29 43 70 74 82 92
Podstawy programowania
Materiały do użytku wewnętrznego
6.39