background image

 

 

Klasa Math

Klasa Math zawiera metody służące do 

wykonywania podstawowych operacji 

matematycznym, takich jak np. potęgowanie, 

logarytmowanie, pierwiastkowanie oraz obliczanie 

wartości z funkcji trygonometrycznych

Klasa Math nie wymaga jawnego importowania – jej 

składowe są dostępne domyślnie

W Javie dostępna jest również inna wersja tej 

biblioteki o nazwie StrictMath, zawierająca 

implementacje wg. FDML (

Freely Distributable Math 

Library

)

background image

 

 

Klasa Math

Wszystkie składowe udostępniane przez klasę Math 

są 

statyczne

, co oznacza, że są dostępne bez 

konieczności tworzenia obiektów tej klasy

Dostęp do składowych klasy Math uzyskuje się 

poprzez wywoływanie ich wprost z klasy, a nie (jak 
to dzieje się np. z metodami klasy String) z obiektu 

takiej klasy

Np. wywołanie metody charAt klasy String wymaga 

istnienia obiektu klasy String, na rzecz którego 

wywołuje się tę metodę

background image

 

 

Metoda charAt jest niestatyczna, więc

musi być wywoływana jest z obiektu

klasy String; próba wywołania jej z 

klasy (np. String.charAt()

spowoduje błąd kompilacji

Przykład

String str = ”ABC”;

char ch = str.charAt(0); // 'A”

double sin0 = Math.sin(0);

Metoda sin klasy Math jest

statyczna, dlatego wywołuje się

ją wprost z klasy (nie z obiektu)

background image

 

 

Użyteczne składowe klasy Math

własność:

static double E;

przybliżenie wartości stałej 

e

 (tzn. podstawy 

logarytmu naturalnego)

przykład:

:
System.out.println(Math.E); // 2.718281828459045
:

background image

 

 

Użyteczne składowe klasy Math

własność:

static double PI;

przybliżenie wartości stałej 

π

przykład:

:
System.out.println(Math.PI); // 3.141592653589793

:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double abs(double a);

static float abs(float a);

static int abs(int a);

static long abs(long a);

obliczenie wartości bezwzględnej argumentu

przykład:

:
System.out.println(Math.abs(-Math.PI));

// 3.141592653589793
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double acos(double a);

obliczenie wartości funkcji 

arccos(a)

przykład:

:

System.out.println(Math.arccos(-1.0));
// 3.141592653589793
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double asin(double a);

obliczenie wartości funkcji 

arcsin(a)

przykład:

:

System.out.println(Math.arcsin(1.0));
// 1.5707963267948966
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double atan(double a);

obliczenie wartości funkcji 

arctg(a)

przykład:

:

System.out.println(Math.arctg(0.0)); // 0.0

:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double cbrt(double a);

obliczenie wartości pierwiastka sześciennego

przykład:

:

System.out.println(Math.cbrt(8.0)); // 2.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double ceil(double a);

obliczenie zaokrąglonej w górę wartości argumentu

(dokładnie: najmniejsza wartość całkowita, większa lub równa 
argumentowi)

przykład:

:
System.out.println(Math.ceil(Math.PI)); // 4.0

:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double cos(double a);

podaje wartość funkcji 

cos(a)

uwaga! 

a

 jest miarą kąta wyrażoną w radianach!

przykład:

:
System.out.println(Math.cos(0.0)); // 1.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double exp(double a);

obliczenie wartości 

e

a

 

przykład:

:
System.out.println(Math.exp(0.0)); // 1.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double floor(double a);

obliczenie zaokrąglonej w dół wartości argumentu

(dokładnie: największa wartość całkowita, mniejsza lub równa 
argumentowi)

przykład:

:
System.out.println(Math.floor(Math.PI)); // 3.0

:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double hypot

(double a, double b);

obliczenie pierwiastka kwadratowego z wyrażenia

(a

2

 + b

2

)

przykład:

:

System.out.println(Math.hypot(3.0, 4.0)); // 5.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double log(double a);

obliczenie wartości 

ln a

przykład:

:
System.out.println(Math.log(Math.E)); // 1.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double log10(double a);

obliczenie wartości 

log a

przykład:

:
System.out.println(Math.log(100.0)); // 2.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double max(double a, double b);

static float max(float a, float b);
static int max(int a, int b);

static long max(long a, long b);

podaje większą z wartości 

a

 i 

b

przykład:

:

System.out.println(Math.max(100.0, 200.0)); // 200.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double min(double a, double b);

static float min(float a, float b);
static int min(int a, int b);

static long min(long a, long b);

podaje mniejszą z wartości 

a

 i 

b

przykład:

:

System.out.println(Math.min(100.0, 200.0)); // 100.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double pow(double a, double b);

oblicza wartość 

a

b

przykład:

:
System.out.println(Math.pow(2.0, 3.0)); // 8.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double random();

podaje wartość pseudolosową 

x

 taką, że 

0 ≤ x < 1

przykład:

:
System.out.println(Math.random()); // ???

:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double rint(double a);

podaje wartość całkowitą (ale w typie double!) 

najbliższą wartości a

przykład:

:

System.out.println(Math.rint(1.5)); // 2.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static long round(double a);

podaje wartość całkowitą (w typie long!) najbliższą 

wartości a

przykład:

:

System.out.println(Math.round(1.5)); // 2
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double signum(double a);

static float signum(float a);

podaje wartość funkcji 

sgn a

przykład:

:
System.out.println(Math.round(-1.5)); // -1.0

:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double sin(double a);

podaje wartość funkcji 

sin a

uwaga! 

a

 jest miarą kąta wyrażoną w radianach!

przykład:

:
System.out.println(Math.sin(Math.PI / 2.0)); // 1.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double sqrt(double a);

podaje wartość pierwiastka kwadratowego z

 

a

przykład:

:

System.out.println(Math.sqrt(100.0)); // 10.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda

:

static double tan(double a);

podaje wartość funkcji 

tg a

uwaga! 

a

 jest miarą kąta wyrażoną w radianach!

przykład:

:

System.out.println(Math.tan(Math.PI / 4.0));
// 0.99999999999999
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double toDegrees(double a);

przelicza miarę kąta a z radianów na stopnie

przykład:

:

System.out.println(Math.toDegrees(Math.PI)); // 180.0
:

background image

 

 

Użyteczne składowe klasy Math

metoda:

static double toRadians(double a);

przelicza miarę kąta 

a

 podaną w stopniach na radiany

przykład:

:
System.out.println(Math.toDegrees(Math.PI)); // 180.0

:

background image

 

 

Deklarowanie klas

Deklarując nową (własną) klasę należy 
dostarczyć informacji o tym:

jak nazywa się nowa klasa (obowiązkowo)

jakie własności ma nowa klasa
(może nie mieć żadnych)

jakie metody ma nowa klasa
(może nie mieć żadnych)

background image

 

 

Najprostsza mozliwa klasa...

...aczkolwiek o wątpliwej przydatności 
praktycznej:

class Klasa { }

background image

 

 

Najprostsza mozliwa klasa

class Klasa { }

Słowo kluczowe class otwiera deklarację nowej klasy

background image

 

 

Najprostsza mozliwa klasa

class Klasa { }

Klasa jest identyfikatorem nowej klasy. 

Nazwa klasy powinna zaczynać się wielką literą.

background image

 

 

Najprostsza mozliwa klasa

class Klasa { }

Nawiasy { i } zawierają ciało deklaracji klasy.

Klasa

 ma puste ciało deklaracji, tzn. 

nie ma żadnego

składnika

 – ani własności, ani metody.

background image

 

 

Deklarujemy zmienną 

obiekt,

która będzie przechowywać

obiekt klasy 

Klasa

Wytworzenie obiektu klasy

class Klasa { }

class Main {

public static void main(String[] args) {

Klasa obiekt;

obiekt = new Klasa();

}

}

Fabrykujemy i podstawiamy pod zmienną

obiekt klasy 

Klasa 

Deklaracja nowej klasy 

Klasa 

background image

 

 

Fabrykowanie i deklaracja

class Klasa { }

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

}

}

Deklarujemy, fabrykujemy i podstawiamy obiekt klasy 

Klasa 

background image

 

 

Czy można wypisać obiekt?

class Klasa { }

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

System.out.println(obiekt);

}

}

Przekazujemy 

obiekt

 metodzie 

println

 – co się stanie?

Na standardowym wyjściu pojawi się napis np:

Klasa@42e816

background image

 

 

Metoda toString

każda klasa

 (nawet pusta) ma metodę toString

 (na 

razie przemilczymy przyczynę tego stanu rzeczy)

metoda  toString  jest  niejawnie  wywoływana  z 

obiektu  zawsze  wtedy,  kiedy  potrzebne  jest 

przekształcenie  danych  zawartych  w  obiekcie  w 

daną łańcuchową

domyślna metoda toString zwraca jako wynik 

unikalny identyfikator obiektu używany wewnętrznie 

przez JVM

definiując nową klasę, możemy podać własną 
metodę toString, bardziej przystającą do naszych 

potrzeb

background image

 

 

Deklarowanie własności

teraz wyposażymy naszą nową klasę w kilka 
własności

na początek zbadamy własności typów 
podstawowych

zadeklarujemy po jednej własności typu int
doublechar i boolean

background image

 

 

Deklarowanie własności

class Klasa {

int i;
double d;
char c;

boolean b;

}

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

}

}

Jak widać, 

deklarowanie własności w klasie

wygląda dokładnie tak samo, jak deklarowanie

zmiennych

background image

 

 

Dostęp do własności obiektu uzyskujemy drogą

znanej już notacji kropkowej

Dostęp do własności

class Klasa {

int i;
double d;
char c;

boolean b;

}

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

obiekt.i = 13;
System.out.println(obiekt.i);

}

}

background image

 

 

Pamiętamy o tym, że własności 

niestatyczne

 istnieją

niezależnie w 

każdym egzemplarzu

 obiektu

(w każdej instancji klasy)

Dostęp do własności

class Klasa {

int i;
double d;
char c;

boolean b;

}

class Main {

public static void main(String[] args) {

Klasa obiekt1 = new Klasa(), obiekt2 = new Klasa();
obiekt1.i = 13; 

obiekt2.i = 31;
System.out.println(obiekt1.i + ” ” + obiekt2.i);

}

}

background image

 

 

Zbadamy, jakie wartości

początkowe są nadawane

własnościom niestatycznym

Wartości początkowe własności

class Klasa {

int i;

double d;
char c;
boolean b;

}

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

System.out.println(”i = ” + obiekt.i);
System.out.println(”d = ” + obiekt.d);
System.out.println(”c = ” + obiekt.c);

System.out.println(”b = ” + obiekt.b);

}

}

background image

 

 

Wartości początkowe własności

Oto wynik:

i = 0
d = 0.0

c =
b = false

background image

 

 

Wniosek

Własności typów prostych 

przybierają początkowe 

wartości wywodzące się z 

zera

byte, short, int, long   0

float, double   0.0

char   '\u0000'

Boolean   false

background image

 

 

Na przykładzie obiektu klasy String

zbadamy teraz, jaka jest

początkowa wartość własności

obiektowych 

Wartości początkowe własności

class Klasa {

int i;
double d;
char c;

boolean b;
String s;

}

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

System.out.println(”s = ” + obiekt.s);

}

}

background image

 

 

Wartości początkowe własności

Oto wynik:

s = null

background image

 

 

Wniosek

Własności obiektowe przyjmują wartość 

początkową 

null

,

a więc

nie reprezentują żadnego obiektu

background image

 

 

Deklarując własności klasy można

określić ich wartości początkowe.

W takim przypadku każdy sfabrykowany

obiekt klasy będzie miał własności

o wskazanych wartościach

Wartości początkowe własności

class Klasa {

int i = 1;

double d = 2.0;

char c = 'C';

boolean b = true;

String s = ”Hello”;

}

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

System.out.println("i = " + obiekt.i);

System.out.println("d = " + obiekt.d);

System.out.println("c = " + obiekt.c);

System.out.println("b = " + obiekt.b);

System.out.println("s = " + obiekt.s);

}

}

background image

 

 

Wartości początkowe własności

Oto wynik:

i = 1

i = 1
d = 2.0

c = C
b = true

s = Hello

background image

 

 

Jeśli deklaracja pewnej własności

jest poprzedzona słowem static, to

będzie ona statyczna. Oznacza to, że

niezależnie od liczby sfabrykowanych

obiektów, taka własność istnieje

tylko w jednym egzemplarzu

.

Własności statyczne

class Klasa {

int i;

static int si;

}

class Main {

public static void main(String[] args) {

Klasa obiekt1 = new Klasa(), obiekt2 = new Klasa();

obiekt1.i++;

obiekt1.si++;

obiekt2.i++;

obiekt2.si ++;

System.out.println(obiekt1.i + ” ” + obiekt1.si);

System.out.println(obiekt2.i + ” ” + obiekt2.si);

}

}

background image

 

 

Wartości początkowe własności

Oto wynik:

i = 1

1 2
1 2

Własności niestatyczne poddano inkrementacji

tylko raz – każdą z osobna

Własność statyczną poddano 

inkrementacji dwukrotnie

background image

 

 

Do własności statycznej

można odwoływać się również

poprzez nazwę klasy

(w wyniku wypisana zostanie liczba 2)

Własności statyczne

class Klasa {

int i;

static int si;

}

class Main {

public static void main(String[] args) {

Klasa obiekt1 = new Klasa(), obiekt2 = new Klasa();

obiekt1.i++;

obiekt1.si++;

obiekt2.i++;

obiekt2.si ++;

System.out.println(Klasa.si);

}

}

background image

 

 

Własności statyczne

Uwaga!

statyczną własność klasy

nazywa się również

zmienną klasy

background image

 

 

Deklarowanie metod

class Klasa {

int i;
int doKwadratu() {

return i * i;

}

}

class Main {

public static void main(String[] args) {

Klasa obiekt = new Klasa();

obiekt.i = 2;
System.out.println(obiekt.doKwadratu());

}

}

Metoda println

wypisze liczbę 4

background image

 

 

Anatomia nagłówka metody

int dodaj(int i)

Określa, czy dana metoda zwraca wynik, a jeśli tak, to jaki:

void oznacza, że metoda nie zwraca żadnego wyniku i że wolno ją 

wywoływać wyłącznie w tzw. pustym kontekście

nazwa typu prostego (np. int) oznacza, że metoda oblicza 

wartość wskazanego typu; można ją wywoływać w kontekście 

typu lub w kontekście pustym – w tym drugim przypadku 

obliczona wartość zostanie odrzucona

nazwa klasy (np. String) oznacza, że dana metoda zwraca 

referencję do obiektu wskazanej klasy; reguły wywoływania są 

takie, jak dla typów prostych

background image

 

 

Anatomia nagłówka metody

int dodaj(int i)

Nazwa metody, wybrana w taki sposób, aby jednoznacznie 

manifestować czynność (bądź obliczenie) wykonywane przez metodę

background image

 

 

Anatomia nagłówka metody

int dodaj(int i)

lista parametrów przekazywanych z zewnątrz do metody.

jeśli metoda nie oczekuje żadnych parametrów, to lista przyjmuje 

postać () - 

użycie słowa kluczowego 

void

 w tym kontekście 

jest błędem!

jeśli metoda przyjmuje więcej niż jeden parametr, ich deklaracje 

rozdziela się je przecinkami, np.

(int a, int b)

background image

 

 

Kontekst wywołania

class Klasa {

void pusta() {

System.out.println(”pusta”);

}

int calkowita() {

System.out.println(”calkowita”);

return 1;

}

}

:

:

Klasa ob = new Klasa();

int zmienna;

zmienna = ob.calkowita();

ob.calkowita();

ob.pusta();

zmienna = ob.pusta();

ŹLE!

background image

 

 

Co może metoda?

metoda może korzystać z 

własności klasy

, w której 

jest zadeklarowana, i może to czynić bez stosowania 
notacji kropkowej (kwalifikowanej). 

jeśli z jakichś powodów skorzystanie z notacji 
niekwalifikowanej prowadzi do konfliktu nazw 

wewnątrz metody, zaleca się korzystanie z notacji 

kwalifikowanej, ale...

...rodzi to ważki problem – jak odwołać się do 

własności obiektu, jeśli się nie wie, jak nazywa się ów 
obiekt?

niejednoznaczność tę rozstrzyga się w taki sposób, iż 
wprowadza się specjalne słowo kluczowe this – 

oznacza ono zawsze ten obiekt, na rzecz którego 
wywołano metodę.

background image

 

 

Przykład

class Klasa {

int a, b;

int podajSumę() {

return a + b;

}

}

Metoda podajSumę odwołuje się do własności a i b klasy 

Klasa – takie odwołanie może być niekwalifikowane (bez 

użycia notacji kropkowej). 

background image

 

 

Przykład

class Klasa {

int a, b;

int podajSumę() {

return a + b;

}

}

class Main {

public static void main(String[] args) {

Klasa ob = new Klasa();

ob.a = 10;

ob.b = 22;

int zm = ob.podajSumę();

System.out.println(zm); // 32

}

}

background image

 

 

Przykład

class Klasa {

int a;

void dodaj(int a) {

this.a += a;

}

}

Widzimy tutaj przykład tzw. 

kolizji nazw

, która 

powoduje niejednoznaczność – nie wiadomo, czy 

a odnosi się do nazwy parametru, czy do nazwy 

własności. 

W Javie przyjęto następujące rozstrzygnięcie:

nazwa parametru (jako bardziej lokalna) 

przesłania

 nazwę własności – tym samym 

nazwa a przestaje w tym kontekście oznaczać 

własność

aby odzyskać dostęp do własności a, należy 

posłużyć się 

kwalifikacją

 względem obiektu 

o nazwie this

background image

 

 

Przykład

class Klasa {

int a;

void dodaj(int a) {

this.a += a;

}

}

class Main {

public static void main(String[] args) {

Klasa ob = new Klasa();

ob.a = 10;

ob.dodaj(11);

System.out.println(ob.a);  // 21

}

}

background image

 

 

Metody statyczne

Tak jak własności, 

metody również mogą być deklarowane jako 

statyczne

 – pociąga to za sobą istotne konsekwencje:

 metoda statyczna może zostać wywołana także wtedy, kiedy nie 
istnieje żaden obiekt klasy – oznacza to, że 

metodzie statycznej nie 

wolno uzyskiwać dostępu do własności niestatycznych

z tego samego powodu 

metodzie statycznej nie wolno wywoływać 

metod niestatycznych

z oczywistych powodów powyższe ograniczenia nie działaja w 
drugą stronę, a więc:

metoda niestatyczna może wywoływać metodę statyczną

 (bo ta 

druga istnieje zawsze)

metoda niestatyczna może używać statycznych własności

 (z tych 

samych powodów)

background image

 

 

Przykład

class Klasa {

int a;

static int sa;

void metoda() {

a++;

sa++;

}

static void smetoda() {

a++;

as++;

}

}

Metoda niestatyczna korzysta z 

niestatycznej własności

DOBRZE

Metoda niestatyczna korzysta ze 

statycznej własności

DOBRZE

Metoda statyczna korzysta z 

niestatycznej własności

ŹLE

Metoda statyczna korzysta ze statycznej 

własności

DOBRZE

background image

 

 

Przykład

class Klasa {

void metoda1() {

}

void metoda2() {

metoda1();

smetoda1();

}

static void smetoda1() {

}

static void smetoda2() {

metoda1();

smetoda1();

}

}

Metoda niestatyczna woła metodę 

niestatyczną

DOBRZE

Metoda niestatyczna woła metodę 

statyczną

DOBRZE

Metoda statyczna woła metodę 

niestatyczną

ŹLE

Metoda statyczna woła metodę 

statyczną 

DOBRZE

background image

 

 

Zagadnienie projektowe

Wyobraźmy sobie następujący problem:

chcemy skonstruować klasę, która pozwoli nam na wygodne i 
bezpieczne operowanie datami

taka klasa powinna przechowywać w sobie konkretną datę oraz 

zawierać zestaw metod służących do wykonywania pożytecznych 
operacji np. obliczania liczby dni pomiędzy dwoma datami

zakładamy, że mechanizmy udostępniane przez tę klasę są 

maksymalnie bezpieczne, tzn. klasa nie wyrazi zgody na to, aby 
używać jej w nieprawidłowy sposób, np. dla zapamiętania daty
30 lutego 2000 roku

wstępnie ustalamy, jakie dane powinna przechowywać klasa i 
dochodzimy do wniosku, że są to:

rok

-  typu int

miesiąc

-

typu int

dzień

-

typu int

background image

 

 

Klasa 'Data' – pierwszy prototyp

class Data {

int

rok;

int

miesiąc;

int

dzień;

}

Na razie nasza klasa składa się tylko z własności i wyraźnie cierpi 

na brak jakichkolwiek metod. W takiej wersji klasa wyraźnie 

przypomina zwykłą strukturę, jaką znamy z języka „C”. Użycie 

takiej klasy pozwala na spójne reprezentowanie i przechowywanie 

dat, ale poza tym pożytek z niej nie jest imponujący.

background image

 

 

Klasa 'Data' w użyciu

class Data {

int

rok;

int

miesiąc;

int

dzień;

}

class Main {

public static void main(String[] args) {

Data nowyrok = new Data();

nowyrok.rok = 2009;

nowyrok.miesiąc = 1;

nowyrok.dzień = 1;

}

}

background image

 

 

Klasa 'Data'

:

:
System.out.println(nowyrok.dzień + ”/” + 
nowyrok.miesiąc + ”/” + nowyrok.rok);

:
:

Wyobraźmy sobie teraz, że chcielibyśmy dysponować wygodnym 

sposobem wypisywania naszej daty w czytelny i elegancki sposób. 

Można to oczywiście zrobić tak jak poniżej, ale nie wydaje się, aby 

było to rozwiązanie budzące entuzjazm programisty...

background image

 

 

Klasa 'Data'

:
:
System.out.println(nowyrok);

:
:

O ileż piękniej byłoby, gdyby można się było posłużyć takim 

eleganckim skrótem myślowym. My przekazujemy metodzie 

println() obiekt klasy Data, a obiekt sam już wie, jaką przybrać 

postać. 

Co jest potrzebne, aby to marzenie stało się faktem?

Potrzebna jest metoda „toString”!

background image

 

 

Klasa 'Data' – drugi prototyp

class Data {

int

rok;

int

miesiąc;

int

dzień;

public String toString() {

return dzień + ”/” + miesiąc + ”/” + rok;

}

}

Dopisujemy do naszej klasy metodę toString, dbając o to, aby jej 

nagłówek wyglądał dokładnie tak, jak w tym przykładzie.

Niebawem wyjaśnimy, czemu jest to niezbędnie konieczne.

Oczywiście, możemy tu zawrzeć dowolny, wybrany przez nas, 

sposób kodowania daty.

background image

 

 

Klasa 'Data' w użyciu

class Data {

int

rok;

int 

miesiąc;

int  

dzień;

public String toString() {

return dzień + ”/” + miesiąc + ”/” rok;

}

}

class Main {

public static void main(String[] args) {

Data nowyrok = new Data();

nowyrok.rok = 2009;

nowyrok.miesiąc = 1;

nowyrok.dzień = 1;

System.out.println(nowyrok);

}

}

background image

 

 

Klasa 'Data' i nadużycie

class Main {

public static void main(String[] args) {

Data dziwna = new Data();

dziwna.rok = 2009;

dziwna.miesiąc = 13;

dziwna.dzień = 1;

System.out.println(nowyrok);

}

}

Niestety, nasza klasa jest 

zupełnie bezbronna wobec 

takich oto nadużyć.

Jak temu zaradzić?

Wyobraźmy sobie, że istnieje 

mechanizm, który wyklucza 

możliwość manipulowania 

własnością klasy poza naszą 

wiedzą. Dzięki niemu 

uzyskujemy pełną kontrolę 

na tym, jak manipuluje się 

wartością własności.

Taki mechanizm nazywa się 

metodami dostępowymi

background image

 

 

Klasa 'Data' – trzeci prototyp

class Data {

int

rok;

int

miesiąc;

int

dzień;

void setMiesiąc(int miesiąc) {

if(miesiąc < 1 || miesiąc > 12)

System.out.println(”No chyba na głowę upadłeś!”);

else

this.miesiąc = miesiąc;

}

}

Metoda dostępowa, której zadaniem jest wpisywanie wartości 

do pewnej własności jest nazywana 

setterem

, a jej nazwa 

powstaje ze sklejenia słowa „set” (ustaw) i nazwy ustawianej 

własności

(z uwzględnieniem konwencji dotyczącej wielkości liter)

background image

 

 

Klasa 'Data' – trzeci prototyp

class Data {

int

rok;

int

miesiąc;

int

dzień;

int getMiesiąc() {

System.out.println(”Jakiż to piękny miesiąc...”);

return miesiąc;

}

}

Metoda dostępowa, której zadaniem jest oczytywanie wartości 

pewnej własności jest nazywana 

getterem

, a jej nazwa powstaje 

ze sklejenia słowa „get” (weź) i nazwy odczytywamek własności

(z uwzględnieniem konwencji dotyczącej wielkości liter)

background image

 

 

Klasa 'Data' użyta bezpiecznie

class Main {

public static void main(String[] args) {

Data dziwna = new Data();

dziwna.rok = 2009;

dziwna.setMiesiąc(1);

dziwna.setMiesiąc(13);

dziwna.miesiac = 13;

dziwna.dzień = 1;

System.out.println(nowyrok);

}

}

Takie postępowanie zostanie 

przez obiekt zaakceptowane

Na to nasz obiekt nie 

pozwoli

Z żalem stwierdzamy, że to 

się – niestety - powiedzie... :(

background image

 

 

Pytanie

Pytanie

:

Czy można sprawić, aby pewna własność była dostępna tylko i 
wyłącznie
 poprzez metody dostępowe i aby była ukryta przed 
oczyma użytkowników klasy?

Odpowiedź

:

Tak, to możliwe. Należy uczynić taką własność 

własnością prywatną

.

background image

 

 

Teraz własność miesiąc jest 

własnością 

prywatną

, co 

oznacza, że nie wolno odwołać 

się do niej poprzez jej nazwę – 

taka własność staje się 

niewidoczna z zewnątrz klasy.

Klasa 'Data' – czwarty prototyp

class Data {

int

rok;

private int

miesiąc;

int

dzień;

int getMiesiąc() {

return miesiąc;

}

void setMiesiąc(int miesiąc) {

if(miesiąc < 1 || miesiąc > 12)

System.out.println(”Nic z tego!”);

else

this.miesiąc = miesiąc;

}

public String toString() {

return rok + ”/” + miesiąc + ”/” + dzień;

}

}

background image

 

 

Takie odwołanie jest poprawne.

Własność rok nie jest prywatna

Klasa 'Data' z własnością prywatną

class Data {

:

:

:

:

}

class Main {

public static void main(String[] args) {

Data nowyrok = new Data();

nowyrok.rok = 2009;

nowyrok.miesiąc = 1;

}

}

Takie odwołanie jest niepoprawne.

Własność miesiąc jest prywatna.

Kompilator zgłosi błąd!

background image

 

 

Podsumujmy

Jeżeli deklaracja pewnej własności jest poprzedzona poprzedzona 
słowem kluczowym private, oznacza to, że własność ta deklarowana 

jest jako 

prywatna

.

Bezpośredni dostęp do 

własności prywatnej

 („dostęp 

po nazwie

”) 

możliwy jest tylko i wyłącznie z wnętrza klasy – próba dostania się do 
niej z innego miejsca wywoła błąd kompilacji.

Możliwy jest jednak dostęp z użyciem metod dostępowych (

getter

 i 

setter

), które dodatkowo pozwalają uzyskać kontrolę na procesem 

modyfikowania i odczytywania wartości własności.

Jako 

prywatna

 może być także zadeklarowana dowolna metoda 

klasy.