Zestaw aktualnie istniejacych obiektów danej klasy



Pobieranie 86,71 Kb.
Data18.04.2018
Rozmiar86,71 Kb.
RodzajReferat

EKSTENSJA KLASY

REFERAT II

GRUPA 623


10 MARCA 2003

AUTORZY:
PIOTR JEDRZEJCZYK



TOMASZ LUCZYNSKI

1.0. Co to jest ekstensja klasy (wg. K. Subieta)
Zestaw aktualnie istniejacych obiektów danej klasy. Zwykle ten termin oznacza specjalna strukture danych skojarzona z dana klasa, której zadaniem jest przechowywanie wszystkich obiektów bedacych wystapieniami tej klasy. Filozofia ta jest uwazana za atawizm, kontynuacje koncepcji modelu relacyjnego, gdzie deklaracja typu tablicy (relacji) byla nierozerwalnie zwiazana z utworzeniem samej tablicy. Dla kazdej deklaracji typu w schemacie relacyjnej bazy danych istniala dokladnie jedna tablica przechowywana w bazie danych. Wielu specjalistów postulowalo rozdzielenie tych dwóch deklaracji. Postulat uniezaleznienia deklaracji typów/klas i odpowiadajacych im obiektów staje sie aktualny w przypadku obiektowosci, której filozofia jest dekompozycja pojec oraz ortogonalna ich kombinacja. Pojecie ekstensji staje sie semantycznie malo spójne w przypadku klas abstrakcyjnych.


    1. Ekstensja klasy jako tablica statyczna.

Jednym ze sposobow implementacji w Javie ekstensji klasy jest uzycie tablicy statycznej w ktorej przechowywane sa wszystkie wystapienia danej klasy. W tym celu nalezy zadbac o to, aby przy kazdym tworzeniu i usuwaniu klasy tablica zawierajaca liste obiektow byla zawsze uaktualniania. W takim podejsciu metody ekstensji klasy (czyli te metody ktore wykonuja operacje na wszystkich wystapieniach danej klasy) zawieraja sie w kodzie implementowanej klasy sa statyczne.


Przyklad kodu:
class Testowa {

private static Testowa ekstensja[] = new Testowa[100];

private static int ekstensjaLicznosc = 0;

private int liczba;


// Konstruktor klasy

public Testowa(int liczba) {

System.out.println("Testowa() konstruktor");

this.liczba = liczba;

// dodajemy do tablicy i zwiekszamy licznosc

ekstensja[ekstensjaLicznosc++] = this;

System.out.println("Licznosc wystapien obiektow tej klasy :"+ekstensjaLicznosc);

}

// metoda klasy



public int dajLiczbe() {

return liczba;

}

// Metoda ekstensji klasy



public static int dajSume() {

int suma = 0;

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

suma += ekstensja[i].dajLiczbe();

}

return suma;



}

// metoda sluzaca do usuwania obiektu

public static void usun(Testowa t) {

System.out.println("Iteracja po "+ekstensjaLicznosc+" elementach tablicy");

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

if (ekstensja[i] == t) {

System.out.println("Usuwam element nr. "+i);

ekstensja[i] = ekstensja[ekstensjaLicznosc-1];

ekstensja[ekstensjaLicznosc--] = null;

break;


}

}

}



}
public class main {

public main() {

Testowa t1 = new Testowa(1);

Testowa t2 = new Testowa(2);

Testowa t3 = new Testowa(3);

System.out.println("Wywolanie metody dajSume():" + Testowa.dajSume());

Testowa.usun(t2);

Testowa.usun(t3);

Testowa.usun(t1);

System.out.println("Wywolanie metody dajSume():" + Testowa.dajSume());

}

public static void main(String[] args) {



new main();

}

}



Wady rozwiazania:

  • Wielkosc tablicy przechowujacej referencje do tworzonych obiektow musi byc podana na etapie kompilacji kodu, co za tym idzie nie jest mozliwe dynamiczne zmienianie jej wielkosci.

Zalety:


  • nie stwierdzono


2.2. Ekstensja klasy jako statyczna tablica alokowana dynamicznie.
Drugim rozwiazaniem jest zastosowanie statycznej tablicy ktorej wielkosc jest alokowana dynamicznie. Dzieki temu unikamy podawania ilosci mozliwych wystapien klasy w czasie kompilacji programu.
class Testowa {

private static Testowa ekstensja[] = new Testowa[0];

private int liczba;

// prywatna metoda dodaj wywolywana przez konstruktor

// dynamicznie zwieksza wielkosc statycznej tablicy i umieszcza

// w niej referencje nowego obiektu

private static void dodaj(Testowa t) {

int licznosc = ekstensja.length;

// tworzenie nowej tablicy i jeden element wiekszej

Testowa ekstensja_new[] = new Testowa[licznosc+1];

// kopiowanie zawartosci starej tablicy do nowej

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

ekstensja_new[i] = ekstensja[i];

}

ekstensja_new[licznosc] = t;



ekstensja = ekstensja_new;

ekstensja_new = null;

}
// Konstruktor klasy

public Testowa(int liczba) {

System.out.println("Testowa() konstruktor");

this.liczba = liczba;

dodaj(this);

}

// metoda klasy



public int dajLiczbe() {

return liczba;

}

// Metoda ekstensji klasy



public static int dajSume() {

int suma = 0;

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

suma += ekstensja[i].dajLiczbe();

}

return suma;



}

// metoda sluzaca do usuwania obiektu

public static void usun(Testowa t) {

int licznosc = ekstensja.length;

// tworzenie nowej tablicy o jeden element mniejszej

Testowa ekstensja_new[] = new Testowa[licznosc-1];

System.out.println("Iteracja po "+licznosc+" elementach tablicy");
int counter = 0;

// kopiowanie elementow tablicy

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

if (ekstensja[i] != t) {

// jezeli natrafiono na element usuwany - nie kopiujemy go

ekstensja_new[counter++] = ekstensja[i];

}

}

ekstensja = ekstensja_new;



ekstensja_new = null;

}

}


public class main {

taka sama jak poprzednio

}
Wady: Przy kazdym stworzeniu i usunieciu obiektu, tablica jest przepisywana co prowadzi do duzego narzutu na moc obliczeniowa, zwlaszcza przy strukturach o duzej ilosci elementow.

Zalety: Sposob prosty i latwy w wytlumaczeniu i implementacji.




3.0. Kolekcje

Kolekcja jest to struktura danych sluzaca do przechowywania i operowania na danych. W porownaniu do tablicy, kolekcja jest klasa posiadajaca metody umozliwiajace na proste dodawanie, usuwanie oraz iterowanie (przegladanie) po elementach w niej zawartych.

Przyklady klas realizujacych funkcje kolekcji w Javie:
HashSet,

TreeSet,


ArrayList,

LinkedList,

HashMap,

TreeMap,


WeakHashMap,

HashTable,

Vector,

Stack
Przyklady (na kolekcji Vector);



  • Stworzenie kolekcji Vector kolekcja = new Vector();

  • Dodanie obiektu do kolekcji kolekcja.add(obiekt);

  • Usuniecie obiektu z kolekcji kolekcja.remove(nrindeksu); lub .remove(obiekt);

Przegladanie kolekcji odbywa sie za pomoca iteratorow. Iteratory umozliwiaja dostep do kazdego elementu kolekcji wedlug okreslonej kolejnosci (najczesciej wg. kolejnosci wstawiania obiektow do kolekcji).


Przyklad wykorzystania iteratora:


Vector kolekcja = new Vector();

Integer liczba_1 = new Integer(2);

Integer liczba_2 = new Integer(5);

Integer liczba_3 = new Integer(8);

kolekcja.add(liczba_1);

kolekcja.add(liczba_2);

kolekcja.add(liczba_3);

Iterator i = kolekcja.iterator();

while (i.hasNext()) {

System.out.println((Integer)i.next());

}

4.0. Ekstensja klasy jako kolekcja obiektow.
Jako ekstensje klasy mozemy uzyc statycznej kolekcji, co w porownaniu z tablica daje mniejszy narzut kodu oraz sprawniejsze (szybsze) dzialanie aplikacji. Uzycie kolekcji obiektow laczy zalety wykorzystania tablicy statycznej oraz statycznej alokowanej dynamicznie.
Przyklad zastosowania kolekcji jako ekstensji klasy:
import java.util.*;
class Testowa {

private static Vector ekstensja = new Vector();

private int liczba;

// Konstruktor klasy

public Testowa(int liczba) {

System.out.println("Testowa() konstruktor");

this.liczba = liczba;

// dodanie referencji do tworzonego obiektu do kolekcji Vector

ekstensja.add(this);

}

// metoda klasy



public int dajLiczbe() {

return liczba;

}

// Metoda ekstensji klasy



public static int dajSume() {

int suma = 0;

Iterator i = ekstensja.iterator();

while (i.hasNext()) {

suma += ((Testowa)i.next()).dajLiczbe();

}

return suma;



}

// metoda sluzaca do usuwania obiektu

public static void usun(Testowa t) {

ekstensja.remove(t);

t = null;

}

}


public class main {

taka sama jak poprzednio

}

5.0. Metoda obiektu a metoda klasowa

Definicja klasy składa się między innymi z metod. Można wyróżnić dwa rodzaje metod :



  • Metody obiektu - operują na atrybutach jednego obiektu, tego dla którego zostały wywołane. Obiekt stanowi argument domyślny dla tych metod.

  • Metody klasy - operują na ekstensji klasy, czyli na atrybutach wszystkich obiektów należących do ekstensji klasy.



Pracownik

Imie

Nazwisko


DataUrodzenia

Pensja

PoliczWiek() – metoda obiektu

PodajWiekNajstarszego() – metoda klasy





5.1. Polimorfizm metod
Polimorfizm metod jest ściśle powiązane z przesłanianiem metod. Przesłanianie polega na tym, że klasa bardziej wyspecjalizowana przesłania jakąś metodę klasy bardziej ogólnej. Podczas wykonywania programu wybierana jest metoda bliżej obiektu w sensie hierarchii dziedziczenia. Przesłonięte metody maja ta sama sygnaturę ale różnią się implementacją .

Polimorfizm jest bardzo ważna cechą obiektowości, polega na tym, że operacja wywoływana za pośrednictwem komunikatu może być różnie wykonana, w zależności od rodzaju obiektu, do którego ten komunikat został wysłany. Innymi słowy jeżeli w hierarchii dziedziczenia występuje przesłonięta metoda, to zostanie wykona ta która jest najbliżej obiektu na rzecz którego wywołano metodę, nie ma tu znaczenia rodzaj odnośnika.


Przykład polimorfizmu:
class Instrument {
public void zagraj() {

System.out.println("nie okreslony dzwiek");

}

}
class Trabka extends Instrument {


public void zagraj() {

System.out.println("trab trab");

}

}
class Talerze extends Instrument {


public void zagraj() {

System.out.println("bach bach");

}

}
public class Polimorfizm {



public static void main(String[] args) {

new Polimorfizm();

}
public Polimorfizm() {

Instrument ins = new Instrument();

ins.zagraj(); //nie okreslony dziwek

ins = new Trabka();

ins.zagraj(); //trab trab

ins = new Talerze();

ins.zagraj(); //bach bach

}

}


Tak więc dzięki polimorfizmowi nie wywoływana jest metoda klasy jakiego rodzaju jest odnośnik na obiekt ins ale sprawdza dokładnie jakiej klasy jest obiekt na którym wywołano metodę.

6.0. Obsługa ekstensji klasy używając klasy pomocniczej.
Obsługa ekstensji klasy używając klasy pomocniczej, polega to na tym, że tworzeniem obiektów i zarządzaniem nimi zajmuje się klasa pomocnicza – kontener.

Klasa pomocnicza posiada metody które pozwalają na dodawanie i usuwanie obiektów innej klasy. Przykład przedstawia właśnie taką klasę Monety, która zarządza ekstensją klasy Moneta :

import java.util.*;
public class OddzielnaKlasa {

public static void main(String[] args) {

new OddzielnaKlasa();

}
public OddzielnaKlasa() {

Monety monety = new Monety();

System.out.println("Stworzylem obiekt zarzadzajacy ekstensja klasy Moneta");


monety.dodajMonete(1);

monety.dodajMonete(4);

monety.dodajMonete(2);

monety.dodajMonete(9);

monety.dodajMonete(4);

monety.dodajMonete(1);


System.out.println(monety);

monety.usunMonete(2);

System.out.println("Usuwam trzeci elemnet");

System.out.println(monety);

monety.usunMonetyOwartosci(1);

System.out.println("Usuwam elemnty o wartosci 1");

System.out.println(monety);

}

}



/* Klasa reprezentujaca monety

*/

class Moneta {



int wartosc; //wartosc monety

public Moneta(int arg) {

wartosc = arg;

}
}
class Monety {


Vector bilon = new Vector(); //do przechowywania obiektów klasy Moneta

/* Funckja dodaje monete do kolekcji tworzac nowy obiekt Monety

*/

public void dodajMonete(int wartosc) {



Moneta tmp = new Moneta(wartosc);

bilon.addElement(tmp);

}

/* Zwraca licznosc kolekcji obiektów



*/

public int policzMonety() {

return bilon.size();

}

/* Zwraca wartosc monet w kolekcji



*/

public int policzWartoscMonet() {

int wartosc = 0;

for (int i = 0; i < bilon.size();i++) {

Moneta tmp = (Moneta)bilon.elementAt(i);

wartosc += tmp.wartosc;

}

return wartosc;



}

/* Usuwa monete na pozycji i , czyli i+1`tą monete

*/

public boolean usunMonete(int i) {



if (bilon.size() <= 0) {

return false;

} else {

bilon.removeElementAt(i);

return true;

}

}



/* Usuwa monety o zadanej wartosci

*/

public boolean usunMonetyOwartosci(int arg) {



if (bilon.size() <= 0) { //sprawdza czy sa elementy

return false;

} else {

Vector nowy = new Vector();

int count = 0;

for (int i = 0; i < bilon.size(); i++) {

Moneta mon = (Moneta)bilon.elementAt(i);

if (mon.wartosc != arg) nowy.addElement(bilon.elementAt(i)); //jezeli nie sa rowne nie przepisywane sa dalej

else count++;

}

System.out.println("Usunieto " + count + " elemnetów.");



bilon = nowy;

}

return true;



}

/* Dzieki tej funkcji mozna oniekt Monety bezpośrednio wyswietlic za pomoca

System.out.pritln(monety);

Zostana wtedy wyswietlone wszystkie dane ekstensji klasy Moneta.

*/

public String toString() {



String mess = "Ekstensja zawiera " + this.policzMonety() + " elementów.\n";

mess += "Ekstensja jest warta " + this.policzWartoscMonet() + ".\n";

for (int i = 0; i < bilon.size(); i++) {

mess += i + " -> " + ((Moneta)bilon.elementAt(i)).wartosc + "\n";

}

return mess;



}

}
Jak widać klasa Monety posiada pełną kontrole nad obiektami klasy Moneta.


6.1 Wady i zalety obsługi ekstensji klasy za pomocą klasy pomocniczej.
Wielką zaletą takiego sposobu obsługi ekstensji jest to że programista posiada kontrole nad tworzeniem i usuwaniu obiektów. Ponadto takie klasy mają dużą funkcjonalność, w przykładzie jest tylko kilka podstawowych funkcji takich jak zliczanie elementów ekstesji, ale można je rozszerzyć o bardziej skomplikowane i równie pożyteczne metody (np. sortowanie).

Jednak taki sposób posiada również wady. Najważniejsza jest to fakt, że jest to najbardziej skomplikowany sposób obsługi ekstensji. Ponad to jakakolwiek zmiana klasy Moneta prawie zawsze wymusza zmienienie metod klasy Monety.



©operacji.org 2019
wyślij wiadomość

    Strona główna