• Nie Znaleziono Wyników

Języki i techniki programowania Ćwiczenia 4 Wzorce

N/A
N/A
Protected

Academic year: 2021

Share "Języki i techniki programowania Ćwiczenia 4 Wzorce"

Copied!
5
0
0

Pełen tekst

(1)

Języki i techniki programowania

Ćwiczenia 4

Wzorce

(2)

Autor: Marcin Orchel Wzorce to metoda generacji różnych klas lub różnych funkcji.

Przykład 1:

Jeśli dana klasa C wykonuje obliczenia numeryczne, i wymaganiem jest przeprowadzanie obliczeń zarówno dla typu float jak i double, np w celach porównawczych to można

zastosować wzorce. Alternatywą byłoby napisanie klasy C dla typu float jak i double, wadą tej metody byłaby redundancja kodu.

Drugą alternatywą byłoby przekazanie do wszystkich funkcji wykonujących obliczenia na typie float lub double abstrakcyjnej klasy bazowej D dla opakowanych typów float i double.

Wady tego rozwiązania:

w ogólności konieczność stworzenia klasy bazowej również dla typów, które nie są ze sobą powiązane.

Konieczność opakowywania typów prostych.

Wszystkie funkcje wykonujące obliczenia na typie D mogłyby być również przeniesione do wnętrza klasy D.

Klasa wzorcowa template<class T> C {

}

Operowanie na klasach wygenerowanych z wzorca:

C<float> o1;

C<double> o2;

Przykład 2:

Jak zrealizować metodę porównującą dwa elementy dowolnego typu?

1. Przekazanie dwóch elementów typu Comparable.

Wadą tego rozwiązania, jest to, że element, który może być porównywany musi dziedziczyć po Comparable.

2. Przekazanie dwóch argumentów typu Object o1 i o2, oraz przekazanie obiektu Comparatora dla dwóch podanych obiektów o1 i o2.

3. Zastosowanie wzorców

template<T> int compare(T o1, T o2) {

return o1.compareTo(o2);

}

Przykład 3:

Często wykorzystujemy listy elementów tego samego typu.

Zapewnienie, że lista będzie miała ten sam typ dla każdego elementu, może wyglądać

następująco:

(3)

po dodaniu pierwszego obiektu do listy zapamiętywany jest typ tego obiektu, przy

dodawaniu następnych obiektów typ tych obiektów jest weryfikowany. Takie sprawdzenie typów odbywałoby się juz w czasie działania programu.

Zapewnienie kontroli typów w czasie kompilacji za pomocą wzorców:

template<T> List {

public : add(T element) {

} };

Teraz juz w trakcie kompilacji sprawdzany jest typ dodawanych obiektów, wszędzie tam gdzie jest używana metoda add.

W Javie można używać list bez genericów, wtedy takie listy dopuszczają różne elementy, lub można używać list z genericami od wersji 1.5.

W C++ biblioteka standardowa zawierająca m.in. różne kolekcje, w tym liste, napisana jest z wykorzystaniem wzorców, a więc stosowanie wzorców jest w tym wypadku konieczne.

W C++ błędy związane z użyciem wzorców sprawdzane są w miejscu użycia wzorca, mogą być również sprawdzane na etapie linkowania.

Błąd, taki, że parametr wzorca T nie ma metody, która jest wywoływana w klasie C, zostanie wykryty na etapie kompilacji przy wywołaniu tej metody.

Różnice między genericami w Javie, a wzorcami w C++.

W Javie nie mozna podawac typow prostych.

W Javie

public static <T> void foo(T arg)

nie można wywołać metody np arg.he() w metodzie foo, ponieważ typ T ma zdefiniowane metody tylko te co są w typie Object.

W C++ można coś takiego zrobić, wtedy przy wywołaniu metody foo sprawdzane jest czy istnieje metoda he() na podanym argumencie.

W Javie generici są tylko informacją dla kompilatora, w kodzie pośrednim nie występują w ogóle informacje o genericach, są one usuwane.

W C++ przy definicji nowej klasy z wzorca klasa ta jest tworzona i kod klasy wzorcowej jest reprodukowany do nowo powstałej klasy.

Pytanie

Jeśli metoda przyjmuje List<Figure> czy mozna podać do tej metody List<Circle>?

Nie można tego zrobić w Javie, ponieważ gdyby było to możliwe to mielibyśmy listę dowolnych figur i moglibyśmy dodać do niej dowolną figurę.

Rozwiązaniem jest List<? extends Figure>, które mówi, że podawany jest jakiś typ

dziedziczący po Figure. W tym wypadku też nie można wywołać funkcji add, ponieważ

wiemy, że jest to jakiś typ dziedziczący po Figure, ale nie wiemy jaki to jest typ.

(4)

W C++ również występuje to zagadnienie, ale nie ma takiego rozwiązania jak w Javie.

Ogólnym rozwiązaniem tego zagadnienia jest zastosowanie templatów.

template<T> foo(List<T> list).

Wtedy możemy podać listę dowolnych elementów.

(5)

Zadania

Zadanie podstawowe

a) Zrobić własną implementację listy jednokierunkowej przechowującej obiekty tego samego dowolnego typu, który posiada operator ==, oraz > wykorzystując do tego wzorce

zaimplementować dla tej listy metodę addElement, removeElement, swapElements, getElement, compareElements,

parametr wzorca opakować typem InternalListElement zawierającym referencję do następnego obiektu

b) Zrobić implementację listy jednokierunkowej bez wzorców, która może

przechowywać elementy typu abstrakcyjnego ListElement, zaimplementować te same metody co w podpunkcie a), typ ListElement powinien zostać opakowany typem InternalListElement

klasa ListElement powinna zawierać metodę compareTo, która będzie wykorzystywana przez metodę compareElements

c) zrobić dziedziczenie w klasie Triangle z klasy ListElement, stworzyć listę elementów typu Triangle zarówno dla sposobu pierwszego jak i drugiego, sprawdzić, czy istnieją dwa trójkąty w liście o tym samym obwodzie Napisać funkcję testującą powyższą funkcjonalność.

Zadanie dodatkowe 1

Zaimplementować globalną funkcję wzorcową sort, która przyjmuje jako parametr listę jednokierunkową wzorcową z pierwszego zadania, oraz jako drugi parametr przyjmuje abstrakcyjną klasę wzorcową Comparator<T>, w której zadeklarowana jest metoda compareElements, odziedziczyć po klasie Comparator<T> komparator dla obiektów Triangle, porównujący pola, zamiast obwodów. Posortować tą funkcją przykładową listę obiektów typu Triangle.

Napisać funkcję testującą powyższą funkcjonalność.

Zadanie dodatkowe 2

Zaimplementować wzorcową listę dwukierunkową z tymi samymi metodami co w zadaniu 1, InternalListElement zawiera referencję do poprzedniego i następnego obiektu

- stworzyć abstrakcyjną klasę List, po której dziedziczą klasy OneDirectionList, TwoDirectionsList

- przerobić funkcję sort, tak aby otrzymywała abstrakcyjną klasę List, zrobić przykładowe sortowanie obiektów Triangle

Napisać funkcję testującą powyższą funkcjonalność.

Cytaty

Powiązane dokumenty

Nale»¡ do nich: pozy- cja mniejszo±ci ªu»yckiej w Niemczech, niski presti» j¦zyka ªu»yckie- go i cichy brak akceptacji ze strony Niemców, aby kultura ªu»ycka staªa

We funkcji main stworzyć tablicę obiektów typu Triangle, utworzyć obiekt klasy Triangles,. wywołać z niego metody wyszukiwania trójkąta o maksymalnym obwodzie, oraz sprawdzania

Jeśli nie jest zdefiniowana w klasie Punto, a jest zdefiniowana w klasie Car i Fiat, to zostanie uruchomiona metoda startEngine() z klasy Fiat.. W

- wszystkie rzucane wyjątki obsłużyć w klasie Figures, która przechowuje zdefiniowaną powyżej listę

Ochrona danych poprzez argumenty typu static. Przeładowanie operatora

Do tego czasu kościelną formą zawarcia małżeństwa było wspólne przyjęcie eucharystii przez nowożeńcówO. oraz modlitwa i błogosławieństwo udzielane przez biskupa

Jeżeli zaś znaleźli by się tacy, którzy by to czynili, to niech będą wy klęci.. Postanawiamy jednak, aby biskup miejscowy miał

Przyjmując, że zmienna dzien jest selektorem instrukcji wyboru case wyprowadzić pełną nazwę dnia tygodnia.. Opracować program realizujący funkcje prostego