Upload
ervin
View
37
Download
0
Embed Size (px)
DESCRIPTION
Luokkien väliset koostesuhteet. Yhteyssuhde eli assosiaatio on yhteys luokkien välillä. Assosiaation erikoismuoto on koostesuhde (aggregation). Tässä mallinnetaan kokonaisuus/osa –suhdetta. Koostesuhde piirretään viivana, jonka kokonaispuolella on ontto vinoneliö. - PowerPoint PPT Presentation
Citation preview
Luokkien väliset koostesuhteet
tMyn 1
Luokkien väliset koostesuhteet
• Yhteyssuhde eli assosiaatio on yhteys luokkien välillä.• Assosiaation erikoismuoto on koostesuhde
(aggregation).• Tässä mallinnetaan kokonaisuus/osa –suhdetta.• Koostesuhde piirretään viivana, jonka kokonaispuolella
on ontto vinoneliö.• Voidaan myös puhua ”has-a” –suhteesta tai ”is-part-of” -
suhteesta.• Koostesuhde (aggregation) ei mitenkään liitä
kokonaisuuden ja osan elinkaaria yhteen.• Esimerkki koostesuhteesta (löyhä koostesuhde)
kuvassa 1.
Luokkien väliset koostesuhteet
tMyn 2
MikkelinPurjehtijat
Purjevene
1
* Tämä luokkaedustaatoisen osaa
Tämä luokkaedustaa”kokonaisuutta”.
Kuva 1. Koosteyhteys (aggregation, löyhä kooste).
Luokkien väliset koostesuhteet
tMyn 3
• Siinä tapauksessa, että koostesuhteeseen halutaan voimakas omistussuhde ja elinkaarien yhteneväisyys, puhutaan vahvasta koosteesta (composite aggregation, composition).
• Tässä tapauksessa osakokonaisuus voi olla osana vain yhdessä vahvassa koosteessa kerrallaan.
• Kokonaisuutta edustavan osuuden on hallittava osiensa elinkaaret.
• Vahva koostesuhde piirretään viivana, jonka kokonaispuolella on täytetty vinoneliö.
• Esimerkki vahvasta koostesuhteesta kuvassa 2.
Luokkien väliset koostesuhteet
tMyn 4
Windows-Ikkuna
Kehys
1
*
Tämä luokkaedustaa toisen osaa – ja voi olla vain yhden kokonaisuuden osana.
Tämä luokkaedustaa”kokonaisuutta”.
Kuva 2. Vahva koosteyhteys (composite aggregation, composition).
Luokkien väliset koostesuhteet
tMyn 5
• Käytännössä koostesuhde rakennetaan siten, että luokka sisältää jonkin toisen luokan ilmentymän tai osoitteen toiseen luokkaan (miksei myös viittauksen).
• Otetaan ensiksi esimerkki löyhästä koostesuhteesta (aggregation). Nyt siis luokkarakenne on hoidettava niin, että osaolio voi/saa jäädä eloon, vaikka koosteolio ei enää olisikaan olemassa.
• Tämä onnistuu, kun toteutetaan koosteluokka niin, että siinä on osoitinviittaus osaolioon.
Luokkien väliset koostesuhteet
tMyn 6
• Kun koosteluokkaan (Laitos) luodaan alla olevassa esimerkissä olio, niin silloin viitataan osoitinmuuttujalla osaluokan (Opettaja) olioon. Osaolion tietojäsenistä ei siis luoda (esim. kopiointimuodostimella) omia ilmentymiä tähän koosteolioon. Yksittäinen opettajailmentymä on siis ”pelkästään” töissä jonkin aikaa laitoksella:
Luokkien väliset koostesuhteet
tMyn 7
#include "stdafx.h"#include <iostream>#include <string>
using namespace System;using namespace std;class Opettaja{public: Opettaja(); ~Opettaja(); void AsetaOpettajanNimi(); void AsetaOpettajanOsoite(); void HaeOpettajanNimi(); void HaeOpettajanOsoite();private: string m_opettajannimi; string m_opettajanosoite;};
”osat”
Kirjoitetaan luokkaan leikki-hajotin, jotta nähdään sentulevan kutsutuksi oikeaan aikaan.
Luokkien väliset koostesuhteet
tMyn 8
Opettaja::Opettaja(){ cout<<"Opettaja-luokan oletusmuodostin, olio "<<this<<endl; AsetaOpettajanNimi(); AsetaOpettajanOsoite();}void Opettaja::AsetaOpettajanNimi(){ cout<<"Anna opettajan nimi: "; getline(cin, m_opettajannimi);}void Opettaja::AsetaOpettajanOsoite(){ cout<<"Anna opettajan osoite: "; getline(cin, m_opettajanosoite);}void Opettaja::HaeOpettajanNimi(){ cout<<"Opettajan nimi on "<<m_opettajannimi<<endl;}
Luokkien väliset koostesuhteet
tMyn 9
void Opettaja::HaeOpettajanOsoite(){ cout<<"Opettajan osoite on "<<m_opettajanosoite<<endl;}Opettaja::~Opettaja(){ cout<<"Opettaja-luokan hajotin, olio "<<this<<endl;}class Laitos{public: Laitos(Opettaja* , string); ~Laitos(); void OsoitaOpettaja(Opettaja*); void AsetaLaitos(string); void HaeLaitoksenOpettajanNimi(); void HaeLaitoksenOpettajanOsoite(); void HaeLaitoksenNimi();
”kokonaisuus”
Luokkien väliset koostesuhteet
tMyn 10
private: // Aggregaatti Opettaja* mp_opettaja; string m_laitoksennimi;};Laitos::Laitos(Opettaja* opettajaolio, string laitoksennimi){ cout<<"Laitos-luokan param. muodostin, olio "<<this<<endl; OsoitaOpettaja(opettajaolio); AsetaLaitos(laitoksennimi);}void Laitos::OsoitaOpettaja(Opettaja* opettajaolio){ mp_opettaja=opettajaolio;}void Laitos::AsetaLaitos(string laitoksennimi){ m_laitoksennimi=laitoksennimi;}
Luokkien väliset koostesuhteet
tMyn 11
void Laitos::HaeLaitoksenOpettajanNimi(){ mp_opettaja->HaeOpettajanNimi();}void Laitos::HaeLaitoksenOpettajanOsoite(){ mp_opettaja->HaeOpettajanOsoite();}void Laitos::HaeLaitoksenNimi(){ cout<<"Laitoksen nimi on "<<m_laitoksennimi<<endl;}Laitos::~Laitos(){ cout<<"Laitos-luokan hajotin, olio "<<this<<endl;}
Luokkien väliset koostesuhteet
tMyn 12
int main(array<System::String ^> ^args){ Opettaja ope=Opettaja(); ope.HaeOpettajanNimi(); {
Laitos eka(&ope, string("Tekniikka ja liikenne"));eka.HaeLaitoksenOpettajanNimi();eka.HaeLaitoksenNimi();
} ope.HaeOpettajanNimi(); return 0;}
Nyt ei eka-olio ole enää olemassa!
Kerrotaan muodostimelle, että kysymyksessäon string-luokan objekti.
Luokkien väliset koostesuhteet
tMyn 13
• Edellisessä esimerkissä voidaan oliot muuttaa muistinvarausluokaltaan dynaamisiksi – kaikki muu pysyisi ennallaan:
Luokkien väliset koostesuhteet
tMyn 14
int main(array<System::String ^> ^args){ Opettaja* ope=new Opettaja(); ope->HaeOpettajanNimi(); Laitos* eka=new Laitos(ope, string("Tekniikka ja liikenne")); eka->HaeLaitoksenOpettajanNimi(); eka->HaeLaitoksenNimi(); delete eka; ope->HaeOpettajanNimi(); delete ope; return 0;}
Luokkien väliset koostesuhteet
tMyn 15
• Tehdään edelliseen esimerkkiin sellainen muutos, että nyt kummassakin luokassa tietojäsenten muistinvarausluokka on dynaaminen. Tässä tapauksessa hajottimetkin ovat tarpeellisia.
• Kuvassa 3 tuosta seuraavasta esimerkistä on UML-kaavio.
Luokkien väliset koostesuhteet
tMyn 16
#include "stdafx.h"#include <iostream>#include <string>
using namespace System;using namespace std;class Opettaja{public: Opettaja(); ~Opettaja(); void AsetaOpettajanNimi(); void AsetaOpettajanOsoite(); void HaeOpettajanNimi(); void HaeOpettajanOsoite();private: string* mp_opettajannimi; string* mp_opettajanosoite;};
Luokkien väliset koostesuhteet
tMyn 17
Opettaja::Opettaja(){ cout<<"Opettaja-luokan oletusmuodostin, olio "<<this<<endl; mp_opettajannimi=new string; AsetaOpettajanNimi(); mp_opettajanosoite=new string; AsetaOpettajanOsoite();}void Opettaja::AsetaOpettajanNimi(){ cout<<"Anna opettajan nimi: "; getline(cin, *mp_opettajannimi);}void Opettaja::AsetaOpettajanOsoite(){ cout<<"Anna opettajan osoite: "; getline(cin, *mp_opettajanosoite);}
Luokkien väliset koostesuhteet
tMyn 18
void Opettaja::HaeOpettajanNimi(){ cout<<"Opettajan nimi on "<<*mp_opettajannimi<<endl;}void Opettaja::HaeOpettajanOsoite(){ cout<<"Opettajan osoite on "<<*mp_opettajanosoite<<endl;}Opettaja::~Opettaja(){ cout<<"Opettaja-luokan hajotin, olio "<<this<<endl; delete mp_opettajannimi; delete mp_opettajanosoite;}
Luokkien väliset koostesuhteet
tMyn 19
class Laitos{public: Laitos(Opettaja* , string); ~Laitos(); void OsoitaOpettaja(Opettaja*); void AsetaLaitos(string); void HaeLaitoksenOpettajanNimi(); void HaeLaitoksenOpettajanOsoite(); void HaeLaitoksenNimi(); private: // Aggregaatti Opettaja* mp_opettaja; string* mp_laitoksennimi;};
Luokkien väliset koostesuhteet
tMyn 20
Laitos::Laitos(Opettaja* opettajaolio, string laitoksennimi){ cout<<"Laitos-luokan param. muodostin, olio "<<this<<endl; OsoitaOpettaja(opettajaolio); mp_laitoksennimi=new string; AsetaLaitos(laitoksennimi);}void Laitos::OsoitaOpettaja(Opettaja* opettajaolio){ mp_opettaja=opettajaolio;}void Laitos::AsetaLaitos(string laitoksennimi){ *mp_laitoksennimi=laitoksennimi;}void Laitos::HaeLaitoksenOpettajanNimi(){ mp_opettaja->HaeOpettajanNimi();}
Luokkien väliset koostesuhteet
tMyn 21
void Laitos::HaeLaitoksenOpettajanOsoite(){ mp_opettaja->HaeOpettajanOsoite();}void Laitos::HaeLaitoksenNimi(){ cout<<"Laitoksen nimi on "<<*mp_laitoksennimi<<endl;}Laitos::~Laitos(){ cout<<"Laitos-luokan hajotin, olio "<<this<<endl; delete mp_laitoksennimi;}
Luokkien väliset koostesuhteet
tMyn 22
int main(array<System::String ^> ^args){ Opettaja* ope=new Opettaja(); ope->HaeOpettajanNimi(); Laitos* eka=new Laitos(ope, string("Tekniikka ja liikenne")); eka->HaeLaitoksenOpettajanNimi(); eka->HaeLaitoksenOpettajanOsoite(); eka->HaeLaitoksenNimi(); delete eka; ope->HaeOpettajanNimi(); ope->HaeOpettajanOsoite(); delete ope; return 0;}
Luokkien väliset koostesuhteet
tMyn 23
Luokkien väliset koostesuhteet
tMyn 24
Kuva 3. UML-kaavio edellisestä esimerkistä, aggregation.
Opettaja
- mp_opettajannimi: string*
- mp_opettajanosoite: string*
+ Opettaja()
+ ~Opettaja()
+ AsetaOpettajanNimi(): void
+ AsetaOpettajanOsoite(): void
+ HaeOpettajanNimi(): void
+ HaeOpettajanOsoite(): void
Laitos
- mp_opettaja: Opettaja*
- mp_laitoksennimi: string*
+ Laitos(opettajaolio: Opettaja*, laitoksennimi: string)
+ ~Laitos()
+ OsoitaOpettaja(opettajaolio: Opettaja*): void
+ AsetaLaitos(laitoksennimi: string): void
+ HaeLaitoksenOpettajanNimi(): void
+ HaeLaitoksenOpettajanOsoite(): void
+ HaeLaitoksenNimi(): void
Luokkien väliset koostesuhteet
tMyn 25
• Seuraava esimerkki sisältää vahvan koosteyhteyden (composition). Nyt osaoliolla ja koosteoliolla on yhtenevä elinkaari.
• Ratkaisu toimii helposti siten, että koosteluokassa on suora viittaus osaolioon. Tällöin osaolio syntyy automaattisesti koosteolion tilanvarauksen yhteydessä, ja osaolio häviää automaattisesti koosteolion tilanvapautuksen yhteydessä. Koosteolion on aina pakko sisältää osaolio.
Luokkien väliset koostesuhteet
tMyn 26
• Sekä koosteluokka että osaolioiden luokat voivat sisältää parametrillisia muodostimia.
• Yleensä koosteluokan muodostimelle välitetään parametreina kaikille muodostimille välitettävät tiedot.
• Koosteluokan muodostimessa ohjataan parametrit edelleen osaolioiden luokkien muodostimelle.
Luokkien väliset koostesuhteet
tMyn 27
#include "stdafx.h"#include <iostream>#include <string>
using namespace System;using namespace std;class Pvm{public: Pvm(int, int, int, int, int); ~Pvm(); void AsetaPaiva(int); void AsetaKuukausi(int); void AsetaVuosi(int); void AsetaTunti(int); void AsetaMinuutti(int); void HaePvm();
Otetaan leikkihajotin mukaan,jotta varmistutaan, että se tulisikutsutuksi oikeassa paikassa.
Luokkien väliset koostesuhteet
tMyn 28
private: int m_paiva; int m_kuukausi; int m_vuosi; int m_tunti; int m_minuutti;};Pvm::Pvm(int paiva, int kuukausi, int vuosi, int tunti, int minuutti){ cout<<"Pvm-luokan 5.param. muodostin, olio "<<this<<endl; AsetaPaiva(paiva); AsetaKuukausi(kuukausi); AsetaVuosi(vuosi); AsetaTunti(tunti); AsetaMinuutti(minuutti);}void Pvm::AsetaPaiva(int paiva){ m_paiva=paiva;}
Luokkien väliset koostesuhteet
tMyn 29
void Pvm::AsetaKuukausi(int kuuukausi){ m_kuukausi=kuuukausi;}void Pvm::AsetaVuosi(int vuosi){ m_vuosi=vuosi;}void Pvm::AsetaTunti(int tunti){ m_tunti=tunti;}void Pvm::AsetaMinuutti(int minuutti){ m_minuutti=minuutti;}
Luokkien väliset koostesuhteet
tMyn 30
Pvm::~Pvm(){ cout<<"Pvm-luokan hajotin, olio "<<this<<endl;}void Pvm::HaePvm(){ cout<<"Ajankohta on "<<m_paiva<<"."<<m_kuukausi<<".” <<m_vuosi<<" klo. "<<m_tunti<<"."<<m_minuutti<<endl;}
Luokkien väliset koostesuhteet
tMyn 31
class Palaveri{public: Palaveri(int, int, int, int, int, string&, string&); ~Palaveri(); void AsetaPaikka(string&); void AsetaAihe(string&); void HaeTiedot(); void HaeAjankohta();private: Pvm m_ajankohta; string m_paikka; string m_aihe;};
Viiteparametrien käyttö”säästää” yhden kopiointitapahtuman.
Luokkien väliset koostesuhteet
tMyn 32
Palaveri::Palaveri(int paiva, int kuukausi, int vuosi, int tunti, int minuutti, std::string& paikka, std::string& aihe):m_ajankohta(paiva, kuukausi, vuosi, tunti, minuutti){ cout<<"Palaveri-luokan muodostin, olio "<<this<<endl; AsetaPaikka(paikka); AsetaAihe(aihe);}
Parametrit välitetään osaolioille kirjoittamalla muodostimen otsikkorivinjälkeen kaksoispisteen jälkeen ne osaoliot, joiden parametrillistamuodostinta halutaan kutsuttavan. Kunkin koosteluokassa määritellynosaolion nimen yhteyteen sulkeisiin kirjoitetaan parametrina välitettävientietojen arvot. Välitettävien parametrien tyypit ja lukumäärä määräävätkutsuttavan muodostimen.
Luokkien väliset koostesuhteet
tMyn 33
void Palaveri::AsetaPaikka(std::string& paikka){ m_paikka=paikka;}void Palaveri::AsetaAihe(std::string& aihe){ m_aihe=aihe;}
Luokkien väliset koostesuhteet
tMyn 34
void Palaveri::HaeTiedot(){ m_ajankohta.HaePvm(); cout<<"Paikkana on: "<<m_paikka<<endl <<"Aiheena on: "<<m_aihe<<endl;}Palaveri::~Palaveri(){ cout<<"Palaveri-luokan hajotin, olio "<<this<<endl;}void Palaveri::HaeAjankohta(){ m_ajankohta.HaePvm();}
Luokkien väliset koostesuhteet
tMyn 35
int main(array<System::String ^> ^args){ //Pvm joku=Pvm(3,9,2009,13,30); //joku.HaePvm(); //Palaveri eka(11, 3, 2009, 14, 45, string("Mikpoli MA307"), string("Neuvottelukunnan kriisipalaveri")); Palaveri* eka=new Palaveri(11, 3, 2009, 14, 45, string("Mikpoli MA307"), string("Neuvottelukunnan kriisipalaveri")); eka->HaeTiedot(); delete eka; //Palaveri eka=Palaveri(11, 3, 2009, 14, 45, string("Mikpoli MA307"), string("Neuvottelukunnan kriisipalaveri")); //eka.HaeTiedot(); return 0;} Kerrotaan muodostimelle, että kysymyksessä
on string-luokan objekti.
Luokkien väliset koostesuhteet
tMyn 36
Luokkien väliset koostesuhteet
tMyn 37
• Edellisessä esimerkissä kummankin luokan tietojäseniä olisi voinut olla muistinvarausluokaltaan dynaamisia. Silloin kumpikin luokka tarvitsisi todellisen hajottimen, kts. seuraava esimerkki.
• Kuvassa 4 tuosta seuraavasta esimerkistä on UML-kaavio.
Luokkien väliset koostesuhteet
tMyn 38
#include "stdafx.h"#include <iostream>#include <string>
using namespace System;using namespace std;
class Pvm{public: Pvm(int, int, int, int, int); ~Pvm(); void AsetaPaiva(int); void AsetaKuukausi(int); void AsetaVuosi(int); void AsetaTunti(int); void AsetaMinuutti(int); void HaePvm();
Luokkien väliset koostesuhteet
tMyn 39
private: int* mp_paiva; int* mp_kuukausi; int* mp_vuosi; int* mp_tunti; int* mp_minuutti;};Pvm::Pvm(int paiva, int kuukausi, int vuosi, int tunti, int minuutti):mp_paiva(NULL),mp_kuukausi(NULL),mp_vuosi(NULL),mp_tunti(NULL),mp_minuutti(NULL){ cout<<"Pvm-luokan muodostin, olio "<<this<<endl; mp_paiva=new int; AsetaPaiva(paiva);
On hyvä ajatus alustaaosoitinmuuttujat muodostimessa.
Luokkien väliset koostesuhteet
tMyn 40
mp_kuukausi=new int; AsetaKuukausi(kuukausi);
mp_vuosi=new int; AsetaVuosi(vuosi);
mp_tunti=new int; AsetaTunti(tunti);
mp_minuutti=new int; AsetaMinuutti(minuutti);}void Pvm::AsetaPaiva(int paiva){ *mp_paiva = paiva;}void Pvm::AsetaKuukausi(int kuukausi){ *mp_kuukausi=kuukausi;}
Luokkien väliset koostesuhteet
tMyn 41
void Pvm::AsetaVuosi(int vuosi){ *mp_vuosi=vuosi;}void Pvm::AsetaTunti(int tunti){ *mp_tunti=tunti;}void Pvm::AsetaMinuutti(int minuutti){ *mp_minuutti=minuutti;}Pvm::~Pvm(){ cout<<"Pvm-luokan hajotin, olio "<<this<<endl; delete mp_paiva; delete mp_kuukausi; delete mp_vuosi; delete mp_tunti; delete mp_minuutti;}
Luokkien väliset koostesuhteet
tMyn 42
void Pvm::HaePvm(){ cout<<"Ajankohta on "<<*mp_paiva<<"."<<*mp_kuukausi<<".” <<*mp_vuosi<<" klo. "<<*mp_tunti<<"."<<*mp_minuutti<<endl;}class Palaveri{public: Palaveri(int, int, int, int, int, string&, string&); ~Palaveri(); void AsetaPaikka(string&); void AsetaAihe(string&); void HaeTiedot(); void HaeAjankohta();private: Pvm m_ajankohta; string* mp_paikka; string* mp_aihe;};
Viiteparametrin käyttö”säästää” yhden kopiointitapahtuman.
Luokkien väliset koostesuhteet
tMyn 43
Palaveri::Palaveri(int paiva, int kuukausi, int vuosi, int tunti, int minuutti, std::string& paikka, std::string& aihe):m_ajankohta(paiva, kuukausi, vuosi, tunti, minuutti),mp_paikka(NULL),mp_aihe(NULL){ cout<<"Palaveri-luokan muodostin, olio "<<this<<endl;
mp_paikka=new string; AsetaPaikka(paikka);
mp_aihe=new string; AsetaAihe(aihe);}void Palaveri::AsetaPaikka(std::string& paikka){ *mp_paikka = paikka;}
Luokkien väliset koostesuhteet
tMyn 44
void Palaveri::AsetaAihe(std::string& aihe){ *mp_aihe = aihe;}Palaveri::~Palaveri(){ cout<<"Palaveri-luokan hajotin, olio "<<this<<endl; delete mp_paikka; delete mp_aihe;}void Palaveri:: HaeTiedot(){ m_ajankohta.HaePvm(); cout<<"Paikkana on: "<<*mp_paikka<<endl <<"Aiheena on: "<<*mp_aihe<<endl;}
Luokkien väliset koostesuhteet
tMyn 45
void Palaveri:: HaeAjankohta(){ m_ajankohta.HaePvm();}int main(array<System::String ^> ^args){ Palaveri* p_yksi = new Palaveri(9,3,2009,13,30, string("Mikpoli MA307"), string("Neuvottelukunnan kriisipalaveri")); p_yksi-> HaeTiedot(); delete p_yksi; return 0;}
Kerrotaan muodostimelle, että kysymyksessäon string-luokan objekti.
Luokkien väliset koostesuhteet
tMyn 46
Yhtä hyvin olio voi olla muistinvarausluokaltaan automaattinen:
Luokkien väliset koostesuhteet
tMyn 47
…int main(array<System::String ^> ^args){ Palaveri yksi=Palaveri(9,3,2009,13,30, string("Mikpoli MA307"), string("Neuvottelukunnan kriisipalaveri")); yksi.HaeTiedot(); return 0;}
Luokkien väliset koostesuhteet
tMyn 48
Kuva 4. UML-kaavio edellisestä esimerkistä, composition.
Pvm
- mp_paiva: int*
- mp_kuukausi: int*
- mp_vuosi: int*- mp_tunti: int*- mp_minuutti: int*
+ Pvm(paiva: int, kuukausi: int, vuosi: int, tunti: int, minuutti: int)
+ ~Pvm()
+ AsetaPaiva(paiva: int): void
+ AsetaKuukausi(kuukausi: int): void
+ AsetaVuosi(vuosi: int): void
+ AsetaTunti(tunti: int): void
+ AsetaMinuutti(minuutti: int): void
+ HaePvm(): void
Palaveri
- m_ajankohta: Pvm- mp_paikka: string*- mp_aihe: string*
+ Palaveri(paiva: int, kuukausi: int, vuosi: int, tunti: int, minuutti: int, paikka:string&, aihe: string&)
+ ~Palaveri()
+ AsetaPaikka(paikka: string&): void
+ AsetaAihe(aihe: string&): void
+ HaeTiedot(): void
+ HaeAjankohta(): void