• Nie Znaleziono Wyników

Definicje klas i obiektów

N/A
N/A
Protected

Academic year: 2021

Share "Definicje klas i obiektów"

Copied!
17
0
0

Pełen tekst

(1)

Definicje klas

i obiektów

(2)

Podstawy

Do tej pory używaliśmy klas jedynie po to, by zdefiniować metodę

main(). Klasy mają znacznie szersze zastosowanie w Java.

W OOP (także w Java) klasy służą do definiowania nowych typów

danych o znacznie większej sile wyrazu niż typy tradycyjne.

Mając definicję klasy możemy tworzyć obiekty typu danej klasy. Klasa

pełni rolę wzorca (schematu budowy) obiektu. Obiekty danej klasy

nazywamy instancjami klasy.

Klasy w Java pozwalają na zastosowanie idei hermetyzacji. Osiąga się to przez wyspecyfikowanie danych i kodu klasy, operującego na danych. Proste klasy mogą zawierać tylko dane lub tylko kod lecz

większość klas zawiera zarówno kod jak i dane.

Zwykle użytkownik nie ma bezpośredniego dostępu do danych obiektu, natomiast ma do dyspozycji metody dostępu do danych, przewidziane w klasie. Klasa definiuje więc interfejs do danych swoich instancji (właściwie: zmiennych instancji).

(3)

Ogólny schemat klasy

W Java definicja klasy rozpoczyna się słowem kluczowym class. Ogólna postać definicji klasy jest następująca:

class nazwaKlasy { typ zmiennaInst_1; // ... typ zmiennaInst_n; typ metoda_1(parametry) { // ciało metody_1 } // ... typ metoda_n(parametry) { // ciało metody_n }

} // koniec definicji klasy

Zobacz:

BoxDemo.java

(4)

Deklaracja obiektów

Wytworzenie obiektu z danej klasy to zadanie dwuetapowe:

Po pierwsze: trzeba zadeklarować zmienną typu danej klasy.

Zmienna taka nie jest obiektem. Jest tylko zmienną mogącą wskazywać na obiekt.

Kod

Box myBox;

Efekt null

myBox

Po drugie: trzeba utworzyć obiekt danej klasy i przypisać go do

zmiennej. Operator new dynamicznie rezerwuje (w czasie

wykonania) obszar pamięci na obiekt i zwraca wskazanie do tego obszaru.

Kod

myBox = new Box();

Efekt

myBox

width height depth

(5)

Konstruowanie obiektu

Postać ogólna:

zmiennaKlasy = new nazwaKlasy();

nazwaKlasy jest nazwą klasy, której obiekt właśnie powołujemy.

Nazwa ta, waraz z ewentualnymi parametrami wyznacza konstruktor klasy. Konstruktor to specjalna metoda, o nazwie takiej jak klasa.

Definiuje ona co trzeba zrobić by utworzyć obiekt danej klasy.

Jeżeli klasa nie posiada konstruktora, to jest wywoływany konstruktor domyślny. Po utworzeniu konstruktora dla klasy konstruktor domyślny nie jest dostępny.

Konstruktory nie posiadają typu wynikowego, nawet void. Dzieje się tak dlatego, że niejawnym typem wynikowym każdego konstruktora jest klasa, której obiekt konstruktor tworzy.

Prócz powołania obiektu, zadaniem konstruktora jest jego

inicjalizacja, tak by po utworzeniu był w pełni sprawnym obiektem. Zobacz: BoxDemo3.java

(6)

Słowo kluczowe this

Czasem metoda obiektu potrzebuje odwołać się do obiektu wywołującego tę metodę.

Umożliwia to słowo kluczowe this. Wewnątrz metody this oznacza obiekt, na rzecz którego wywołano metodę.

this jest często używany do tworzenia metod polimorficznych,

ale o tym opowiemy później.

W Java nie można deklarować dwóch takich samych zmiennych lokalnych w obrębie jednego zakresu, jednak istnieje możliwość

przesłonięcia zmiennych instancyjnych klasy przez parametry metody. Wewnątrz metody zmienne instancyjne byłyby niedostępne, gdyby nie możliwość użycia zmiennej this:

Box (double width, double height, double depth){ this.width = width;

this.height = height; this.depth = depth; }

(7)

Zbieracz śmieci

Operator new dynamicznie rezerwuje pamięć na tworzony obiekt. Można się zastanowić jak obiekty są niszczone a ich pamięć

zwalniana.

W niektórych językach (np. C++) obiekty zarezerwowane dynamicznie muszą być zwalniane ręcznie poleceniem delete (lub podobnym). W Java przyjęto inne rozwiązanie. JVM posiada mechanizm zwany

zbieraczem śmieci (ang.: garbage collection), który

automatycznie zwalnia pamięć przydzieloną obiektom, do których

brak jakichkolwiek odwołań.

Zbieracz śmieci włącza się sam, gdy jest co posprzątać. Nie ma jednej reguły jego włączania i wyłączania się.

Różne JVM posiadają różne algorytmy zbierania śmieci, lecz mają

jedną wspólną cechę: programista nie musi pamiętać o zwalnianiu

(8)

Metoda finalize

Ze zbieraczem śmieci związana jest metoda finalize. Zbieracz

śmieci zaraz przed zwolnieniem obiektu uruchamia metodę finalize zwalnianego obiektu.

Metoda ta jest stosowana, gdy obiekt rezerwuje pewne nie-Javowe zasoby, które muszą być zwolnione w specjalny sposób, np:

deskryptory plików, czy fonty.

Na metodzie tej nie możemy opierać poprawności implementowanego algorytmu, ponieważ nie wiemy, kiedy zostanie wywołana przez

zbieracz śmieci.

Postać metody:

protected void finalize() { // tu kod metody

(9)

Przeciążanie metod

W Java możemy definiować wiele metod o tej samej nazwie w obrębie jednej klasy. Metody takie nazywamy przeciążonymi. Muszą one

różnić się typami i/lub liczbą argumentów. Mogą także różnić się typami wynikowymi ale nie wystarcza to by metody były różne.

Zobacz: OverloadDemo.java

Metody przeciążone wspierają polimorfizm.

W językach nie pozwalających na przeciążanie metod/funkcji często dla wyrażenia podobnych operacji dla różnych typów wejściowych

trzeba używać różnych nazw. Np. w C funkcja abs() zwraca wartość bezwzględną liczby całkowitej, labs() długiej liczby całkowitej,

fabs() liczby rzeczywistej, ... .

W Java dzięki przeciążaniu metod można zdefiniować jedną nazwę metody działającą na różnych typach.

Zobacz: AbsDemo.java

W podobny sposób jak zwykłe metody, możemy przeciążać także

(10)

Przekazywanie parametrów

Obiekty jako parametry metod. Ponieważ klasy w Java są

traktowane jak typy w tradycyjnych językach programowania, to

można przekazywać obiekty (parametry typu klasowego) do metod i zwracać obiekty jako wartości. Zobacz: ParameterDemo.java

Przekazywanie parametrów metod przez wartość i zmienną.

W Java sposób przekazywania parametrów do metody zależy od ich typu. Parametry typów prostych zawsze są przekazywane przez

wartość, natomiast przekazywanie obiektów do metod zawsze odbywa się przez zmienną.

Przyponienie pojęć:

Przekazywanie przez wartość: przekazywane wartości nie ulegają

trwałym zmianom - po wywołaniu metody wartość jak przed

Przekazywanie przez zmienną: przekazywane wartości ulegają

trwałym zmianom - po wywołaniu metody wartość się zmienia

(11)

Kontrola dostępu

Klasy definiowane dotychczas nie posiadały ważnej cechy

programowania obiektowego: hermetyzacji, tj. oddzielenia świata

zewnętrznego od danych klasy (patrz Stack.java).

Java pozwala na kontrolę dostępu na poziomie pakietu, klasy i

komponentu klasy. Realizowana jest ona za pomocą słów kluczowych

(specyfikacji kontroli dostępu):

public elementy są dostępne dla dowolnego innego kodu programu

także spoza klasy

private dla elementu klasy sprawia, że jest on dostępny tylko dla

innych elementów tej samej klasy

protected ma zastosowanie w procesie dziedziczenia klas

(omówimy później)

Domyślną specyfikacją kontroli dostępu, tj. gdy nic nie wyspecyfikowano, jest public.

(12)

Elementy static

Zwykle by móc używać elementów zdefiniowanych w klasie, musimy najpierw utworzyć obiekt będący instancją danej klasy. Istnieje jednak możliwość zdefiniowania elementów, do których nie musimy się

odwoływać za pośrednictwem obiektów. Do wyróżnienia takich

elementów służy słowo kluczowe static. Typowym przykładem jest metoda main(). static może być stosowane do:

Zmiennych instancji: są one wówczas zmiennymi globalnymi

wszystkich obiektów danej klasy. Utworzenie obiektu danej klasy nie

powoduje powstania statycznej zmiennej instacji.

Metod: podlegają one następującym restrykcjom:Mogą wywoływać tylko inne metody statyczne

Mogą korzystać wyłącznie ze zmiennych statycznychNie mogą odwoływać się do zmiennych this i super

Jeżeli trzeba wykonać obliczenia by zainicjalizować zmienne

statyczne, można zdefiniować blok static. Będzie on wykonany tylko raz, gdy klasa jest po raz pierwszy załadowana.

Zobacz: Static1.java i

(13)

Elementy final

Słowo kuczowe final służy do oznaczenia zmiennych, których

wartość ma być niezmienna we wszystkich instancjach. Pełnią one rolę stałych i muszą być inicjalizowane przy deklaracji. Przykłady:

final int FILE_NEW = 1; final int FILE_OPEN = 2; final int FILE_SAVE = 3; final int FILE_QUIT = 4;

Dalsza część programu może używać powyższych zmiennych jak stałych. Dodatkowo nie zajmują one miejsca w instancjach klasy. Przyjętą konwencją jest pisanie zmiennych final dużymi literami.

Słowo kuczowe final może również być zastosowane do metod, lecz znaczenie takiego zastosowania jest zupełnie inne niż w przypadku

zmiennych. Zastosowanie final do metod wyjaśnimy podczas omawiania dziedziczenia klas.

(14)

Tablice

Omawiając tablice nie wspomnieliśmy, że są one implementowane jako obiekty. Jako obiekty posiadają specjalny atrybut length

reprezentujący liczbę elementów jakie tablica może przechowywać (a nie ich aktualną liczbę).

class Length {

public static void main(String args[]) { int a1[] = new int[10];

int a2[] = {1, 2, 3, 4, 5, 6, 7, 8}; int a3[] = {4, 3, 2, 1};

int c = a1.length + a2.length + a3.length; System.out.println(c);

} }

(15)

Klasy wewnętrzne

W Java istnieje możliwość definiowania klasy wewnątrz innej klasy. Klasy takie nazywa się klasami zagnieżdżonymi. Zakres klasy wewnętrznej jest ograniczony klasą zewnętrzną, tj.:

Jeżeli klasa B jest zdefiniowana wewnątrz klasy A, wówczas B jest znana wewnątrz A, natomiast nie jest poza A.

Klasa wewnętrzna posiada dostęp do wszystkich elementów klasy zewnętrznej (nawet prywatnych), natomiast klasa zewnętrzna nie posiada dostępu do elementów klasy wewnętrznej.

Istnieją dwa rodzaje klas wewnętrznych:

Statyczne: zdefiniowane ze słowem kluczowym static. Nie mogą

odwoływać się one do elementów klasy zewnętrznej (niestatycznej) wprost. Muszą zdefiniować obiekt klasy zewnętrznej i odwoływać się za jego pośrednictwem; rzadko używane.

Niestatyczne: najczęściej używane. Mają dostęp do wszystkich

elementów klasy zewnętrznej tak jak jej metody niestatyczne

Zobacz: Inner1.java Inner2.java

(16)

Klasa String

Klasa String jest prawdopodobnie najczęściej używaną klasą języka Java, ponieważ każdy napis używany w programie jest obiektem klasy

String. Dotyczy to także napisów stałych, np.:

System.out.println(“To jest napis”);

Napis “To jest napis” jest obiektem klasy String.

Obiekty klasy String są niezmienne, tj. raz utworzone nie mogą

zmieniać swojej zawartości. Jeżeli chcemy zmienić zawartość napisu, trzeba utworzyć nowy zmodyfikowany.

W Java istnieje także klasa StringBuffer pozwalająca na dokonywanie zmian w przechowywanych napisach.

Obiekty klasy String posiadają metody (m.in.)

boolean equals(String o) równość dwóch napisówint length() długość napisu

char charAt(int i) znak na pozycji i

(17)

Parametry linii komend

W Java, pododnie jak w innych językach programowania, istnieje

możliwość przekazania parametrów wywołania programu do metody

main(). Parametry te są przekazane do programu jako tablica

elementów typu String. Następujący program wypisuje wszystkie argumenty, z którymi został wywołany:

class CommandLine {

public static void main(String args[]) { for(int i = 0; i < agrgs.length; i++) System.out.println(“arg[“ + “] =” + args[i]);

} }

Przykładowe wywołanie:

$ java CommandLine to tylko test

Cytaty

Powiązane dokumenty

4-biegowa sekwencyjna synchronizowana skrzynia biegów z silnikiem RC

Podaj nazwę kategorii znaczeniowej rzeczowników pochodnych, do której należy rzeczownik czytelniczka i podkreśl jego formant, a następnie za pomocą tego samego formantu

Prosimy o sprawdzenie, czy telefon komórkowy jest wyłączony a kalkulator i inne pomoce naukowe (np. tablice ma- tematyczne) schowane. Zbadaj zbieżność ciągów i znajdź ich

Prosimy o sprawdzenie, czy telefon komórkowy jest wyłączony a kalkulator i inne pomoce naukowe (np. tablice ma- tematyczne)

pojęcia przestrzeni, gdzie przestrzeń traktuje się jako zbiór elementów spełniających określone postulaty.. Vzychodząc z takiego założenia,

2-biegowa sekwencyjna mocna skrzynia biegów

Zasadniczo rzecz biorąc, współczesna praktyka projektowa w wymiarze designu doświadczeń została sprowadzona do totalitaryzmu semantyk, przeciwko któremu trudno się buntować,

Każdą z pozostałych krzywych odróżnia afinicznie od innych własność uwidoczniona w nazwie (np. ta, że zbiór jest pusty, że jest prostą, że jest sumą dwóch