Autor: Krzysztof
PO 2018: Wejściówka na Lab.13
Do klasy bazowej wybranej do realizacji na lab. 12 (reprezentującej silnik samochodowy albo samochód albo urządzenie optyczne albo osobę na uczelni) dodaj przeciążony operator +=
jako metodę należącą do klasy. Zaproponuj własną logikę sumowania obiektów (np. gdyby to było sumowanie kwadratów, to wynikiem sumowania może być kwadrat, którego pole jest sumą pól składników sumy, albo którego bok ma długość równą sumie długości boków składników sumy). Korzystając z kodu wejściówki na lab. 12 utwórz listę dynamiczną zawierającą 5 elementów typu klasy bazowej, po czym zsumuj je korzystając z napisanego operatora. Na koniec wywołaj metodę wypisz
na rzecz obiektu przechowującego wartość sumy.
Hint: na lab.13 będą rozwijane programy napisane na lab.12.
PO 2018: Wykład 11 – slajdy
PO 2018: Wejściówka na Lab.12
Zaprojektuj i zaimplementuj cztery klasy, które na zajęciach 12 posłużą jako klasy bazowe. Klasy reprezentują pojęcia:
- silnik samochodowy – zawiera pola przechowujące cechy wspólne dla wszystkich silników (moc, wymiary).
- samochód – zawiera pola przechowujące cechy wspólne dla wszystkich samochodów (cena, rodzaj silnika).
- urządzenie optyczne – zawiera pola przechowujące cechy wspólne dla wszystkich takich urządzeń (zoom, waga).
- osoba na uczelni – zawiera pola przechowujące cechy wspólne dla wszystkich takich osób (imię i nazwisko, adres e-mail).
Wszystkie pola klasy bazowej powinny być zadeklarowane jako protected
. Dla każdego z pól powinny istnieć odpowiednie getery i setery. Ponadto każda klasa musi mieć metodę wypisz
, która wypisze w oknie konsoli wartości wszystkich pól.
Do wszystkich klas zaprojektuj po trzy konstruktory: konstruktor domyślny, kopiujący oraz z argumentami przechowującymi wartości dla inicjalizacji wszystkich pól.
Dodatkowo każda klasa bazowa powinna mieć jeszcze pole nast
, zadeklarowane jako public
i zawierające wskaźnik typu takiego jak klasa bazowa. Tym sposobem obiekty klasy bazowej będą mogły być wykorzystane jako elementy listy dynamicznej jednokierunkowej.
Zademonstruj poprawność działania zaprojektowanych klas, pisząc w funkcji main
kod, budujący dla każdego z typów danych listę dynamiczną jednokierunkową zawierającą 5 elementów. Do tworzenia elementów listy użyj konstruktorów domyślnych. Po utworzeniu każdej z list wywołaj metodę wypisz
na rzecz każdego z elementów listy. Na koniec usuń wszystkie listy.
PO 2018: Wykład 10 – slajdy
PO 2018: Wejściówka na Lab.11
W programie będącym rozwiązaniem wejściówki na lab.10 do klasy MojaKlasa
(reprezentującej grupę studencką) dodaj metodę szukaj
, działającą rekurencyjnie, tj. tak jak pokazano na slajdzie 144, wykład 9. Metoda szukaj
znajduje w liście dynamicznej obiekt – grupę studencką o podanym ID (dodaj pole ID
do klasy MojaKlasa
). Do klasy Wykladowca
również dodaj metodę szukaj
, która wywołuje szukaj
na rzecz grup studenckich w liście dynamicznej.
W funkcji main
po utworzeniu obiektu reprezentującego wykładowcę oraz listy co najmniej pięciu grup studenckich przypisanych do tego wykładowcy, wywołaj na rzecz tego obiektu metodę szukaj
, która znajduje w jego liście grupę studencką o podanym ID. Przetestuj działanie szukaj
zarówno dla przypadku, gdy grupa studencka o wskazanym ID istnieje, oraz dla przypadku, gdy takiej brak.
W destruktorze klasy MojaKlasa
zastosuj rekurencyjne usuwanie następnego elementu w liście (slajd 143, wykład 9) i wykorzystaj ten sposób usuwania list dynamicznych.
Napisz klasę Pracownik
, która będzie klasą bazową dla klasy Wykladowca
i przenieś do niej wszystkie pola z klasy Wykladowca
oraz metodę wypisz
. W klasie Wykladowca
zostaw tylko metody dodaj_klase
oraz szukaj
. Ustaw prawa dostępu tak, aby użytkownik obiektów typu Wykladowca
nadal mógł wywoływać metodę wypisz
. Zastanów się nad przeniesieniem części kodu z konstruktorów i destruktorów klasy Wykladowca
do klasy Pracownik
(np. na pewno instrukcje usuwania dynamicznej listy grup studenckich przypisanych do danego wykładowcy powinny być przeniesione do destruktora klasy Pracownik
). We wszystkich konstruktorach jak najwięcej pól inicjalizuj w liście inicjalizatorów konstruktora.
Hint: na zajęciach lab. 11 będzie trzeba rozbudować kod programu napisanego na lab.10.
PO 2018: Wejściówka na Lab.10
Do klasy MojaKlasa
(https://troja.uksw.edu.pl/programowanie-obiektowe/kody-programow/: Program #6) dodaj pole nast
, tak aby można było tworzyć listę dynamiczną jednokierunkową obiektów typu MojaKlasa
.
Następnie zaprojektuj nową klasę Wykladowca
, która zawiera pole typu MojaKlasa*
wskazujące na listę dynamiczną jednokierunkową. Pole to ma pełnić rolę głowy dynamicznej listy grup studenckich przypisanych do danego wykładowcy. Klasa Wykladowca
może też zawierać inne pola, jeżeli okażą się potrzebne.
Do klasy Wykladowca
dodaj konstruktory:
- konstruktor domyślny, inicjalizujący obiekt tak, aby lista dynamiczna była pusta.
- konstruktor z argumentem reprezentującym nazwę pliku tekstowego. Plik zawiera listę kilku adresów e-mail. Konstruktor tworzy jeden obiekt dynamiczny typu
MojaKlasa
, do którego zostają zapisane adresy e-mail odczytane z pliku. Następnie obiekt ten jest dołączany do listy dynamicznej. - konstruktor kopiujący, który tworzy kopię listy dynamicznej z obiektu podanego w argumencie wywołania.
oraz destruktor, który zwalnia wszystkie dynamicznie zaalokowane zasoby.
Do klasy Wykladowca
dodaj metodę dodaj_klase
dodającą nowy obiekt do listy dynamicznej. Argumentem wywołania metody jest nazwa pliku tekstowego z listą adresów mailowych. W metodzie tworzony jest nowy obiekt dynamiczny typu MojaKlasa
, zapisywane są w nim adresy mailowe ze wskazanego pliku, a na koniec obiekt jest dołączany do listy.
Do klasy Wykladowca
dodaj też metodę wypisz
, która wypisuje w oknie konsoli wszystkie grupy studenckie przypisane do danego wykładowcy, tj. dla każdego elementu listy dynamicznej wypisuje wszystkie zapisane w nim niepuste adresy mailowe.
Zademonstruj działanie napisanego kodu: w funkcji main
utwórz obiekty dynamiczne typu Wykladowca
z wykorzystaniem wszystkich trzech konstruktorów, do wybranego z wykładowców dodaj kilka nowych grup studenckich (metodą dodaj_klase
), po czym dla każdego z wykładowców wywołaj metodę wypisz
. Na koniec usuń obiekty dynamiczne typu Wykladowca
, przy czym z pomocą debuggera upewnij się, że destruktor za każdym razem prawidłowo zwolnił wszystkie dynamicznie zaalokowane zasoby.
Przygotuj odpowiedź na pytanie prowadzącego: ile razy w napisanym programie zostały wywołane konstruktory, które i w których miejscach kodu to nastąpiło. A ile razy zostały wywołane destruktory?
Hint: na zajęciach lab. 10 będzie trzeba rozbudować kod programu napisanego na lab.9. Dlatego warto przejrzeć dotychczas napisany kod i usunąć wszystkie ewentualne błędy i niedoróbki.
PO 2018: Wykład 9 – slajdy
PO 2018: Wejściówka na Lab.9
Zaprojektuj klasę, reprezentującą figurę na płaszczyźnie: trapez równoramienny.
Zaproponuj zestaw pól dla tej klasy, pozwalający na jednoznaczne określenie jej położenia na płaszczyźnie względem początku układu współrzędnych oraz jednoznacznie określający jej rozmiary (np. długości boków, podstawy, itd.). Dla uproszczenia przyjmij, że trapez jest zawsze rysowany w określonej pozycji, np. podstawą równolegle do osi X. Projektując zestaw pól postaraj się zminimalizować ich liczbę, dobierając je tak, aby pozostałe brakujące wartości dało się wyznaczyć. Np. gdyby to dotyczyło kwadratu, to do określenia położenia wystarczą współrzędne jednego z wierzchołków, np. lewy-dolny, a do określenia rozmiarów – długość jednego boku. Za pomocą tych wartości jesteśmy już w stanie łatwo wyznaczyć w kwadracie współrzędne wszystkich pozostałych wierzchołków oraz długości pozostałych boków.
Zbiór pól reprezentujących położenie trapezu powinien być rozłączny ze zbiorem pól reprezentujących jego rozmiary, tak aby ewentualne operacje zmiany położenia nie obejmowały modyfikacji pól rozmiaru, a np. skalowanie nie modyfikowało pól położenia. Gdyby to dotyczyło kwadratu, to np. zbiór pól reprezentujących dwa wierzchołki, lewy-dolny i lewy-górny stanowi zły model. Mimo, że pozwala w pełni opisać kwadrat, jednak długość boku jest ukryta w danych o położeniu wierzchołków, więc operacja skalowania rozmiaru modyfikowałaby położenie jednego z wierzchołków.
Wszystkie pola mają być niedostępne z zewnątrz (zadeklarowane jako private
).
Do klasy dodaj trzy metody zadeklarowane jako publiczne:
- Pierwsza – ma ustalać położenie i rozmiary figury, tj. modyfikować wartości pól opisujących położenie i rozmiar. Nowe wartości dla pól powinny być podawane w argumentach wywołania metody. Metoda powinna kontrolować poprawność wartości podawanych w argumentach wywołania i jeżeli są nieprawidłowe (np. ujemne długości boków) powinna je zastępować bezpiecznymi wartościami domyślnymi.
- Druga – powinna wypisywać wartości wszystkich pól figury w oknie konsoli oraz dodatkowo wypisywać aktualne współrzędne wszystkich jej wierzchołków i długości boków wyliczone na podstawie wartości pól.
- Trzecia – powinna wyrażać przekształcenie symetrii osiowej względem prostej opisanej równaniem x=n, tj. jako argument powinna przyjmować wartość rzeczywistą n, a w swoim działaniu powinna przeliczyć wszystkie wartości tych i tylko tych pól, które są odpowiedzialne za położenie tak, aby w rezultacie tego działania przyjęły one wartości określające położenie figury po przekształceniu.
Napisz program, który w funkcji main
deklaruje obiekt typu trapez
, po czym:
- inicjalizuje go wartościami pobranymi od użytkownika, tak aby powstał prawidłowy trapez, korzystając z metody nr 1,
- wywołuje na rzecz tego obiektu metodę nr 2 wypisującą wszystkie pola i współrzędne w oknie konsoli,
- prosi użytkownika o podanie argumentu dla metody symetrii osiowej i wywołuje na rzecz tego obiektu metodę nr 3,
- ponownie wywołuje na rzecz tego obiektu metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby zobaczyć nowe położenie figury,
- ponownie wywołuje na rzecz tego obiektu metodę symetrii osiowej z tym samym argumentem co poprzednio,
- a na koniec jeszcze raz wywołuje metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby sprawdzić, czy figura wróciła na swoje miejsce.
Zadanie wymaga wykazania się umiejętnościami nie tylko programowania obiektowego, ale również modelowania obiektowego. Przystępując do rozwiązania należy najpierw zaproponować model figury geometrycznej zawierający tylko cechy istotne dla działań, jakie są planowane do wykonania na tej figurze (abstrakcja, tj. pomijanie w modelu rzeczy nieistotnych).