ΣΥΣΧΕΤΙΣΕΙΣ ΚΛΑΣΕΩΝ (Class relationships) Σκοπός Σκοπός των συσχετίσεων είναι να αναπαριστούν την αλληλεπίδραση μεταξύ των κλάσεων και των αντικειμένων. Απεικονίζονται διαγραμματικά με μία γραμμή μεταξύ των κλάσεων που αλληλεπιδρούν. Είδη Τα είδη στα οποία διακρίνονται οι συσχετίσεις είναι τα ακόλουθα πέντε: Εξάρτησης ή Χρήσης (Dependency ή Uses) Σύνδεσης (Association) Συναρμολόγησης ή Συγκρότησης (Aggregation) Σύνθεσης (Composition) Γενίκευσης-Ειδίκευσης (Generalisation-Specification) Εξάρτησης ή Χρήσης (Dependency ή Uses) Η συσχέτιση της εξάρτησης αναπαριστά μια προσωρινή επικοινωνία μεταξύ 2 αντικειμένων. Ενα αντικείμενο της κλάσης Α δέχεται παραμετρικά σε κάποια μέθοδό του ένα αντικείμενο της κλάσης Β, ώστε να χρησιμοποιήσει κάποια λειτουργία του (μέθοδο). Δεν απαιτείται επομένως κάποια συγκεκριμένη σχέση μεταξύ των δύο αντικειμένων, διότι δεν εξυπηρετεί τίποτε το να διατηρήσουμε κάποια γνώση σχετικά με την εν λόγω επικοινωνία. Υλοποίηση στην java Δεν απαιτείται αναφορά του Β αντικειμένου στα πεδία της κλάσης Α. Το αντικείμενο της κλάσης Β περνάει παραμετρικά σε κάποια μέθοδο του αντικειμένου της κλάσης Α. Παράδειγμα Το Αυτοκίνητο θέλει να βάλει καύσιμα auto.setkaysima( ) και σταματά σε Βενζινάδικο (pk) για να γεμίσει το ρεζερβουάρ του με καύσιμα pk.gemizeikaysima(auto). Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 1
UML μοντελο Κώδικας class Autokinito { private String arkykloforias; Autokinito(String arkykloforias) { this.arkykloforias = arkykloforias; void setkaysima(pratiriokaysimwn pk, int litra) { pk.gemizeikaysima(this, litra); // το this σημαίνει ότι το αυτοκίνητο στέλνει τον // εαυτό του στο πρατήριο καυσίμων void gemisma(int litra) { System.out.println("... gemizei me " + litra + " litra kaysima to rezerbouar tou " + this); // this to paron antikeimeno public String getarkykloforias() { return arkykloforias; return ("autikinitou me ar. kykloforias " + arkykloforias); class PratirioKaysimwn { private String thesi; PratirioKaysimwn(String thesi) { this.thesi = thesi; Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 2
void gemizeikaysima(autokinito auto) { System.out.print("To Pratirivn kaysimwn " + thesi); auto.gemisma(50); // Sxesi Dependency_Demo class Dependency_Demo { public static void main(string argv[]) { // Anexartita antikeimena, dixws sysxetiseis Autokinito auto = new Autokinito("VW NZX-2334"); PratirioKaysimwn pk = new PratirioKaysimwn("Zagoras"); // Gemisma kaysimwn KartoTilepfonou System.out.println("\nGemisma Kaysimwn"); System.out.println("-------------------"); int litra = UserInput.getInteger("\nDwse litra venzinis: "); auto.setkaysima(pk, litra); //parametriko perasma tou pk sto auto Σύνδεση (Association) Η συσχέτιση της Σύνδεσης αναπαριστά μια αμφίδρομη (προαιρετικά) επικοινωνία μεταξύ 2 αντικειμένων, για την οποία θέλουμε να διατηρηθεί η γνώση. Υλοποίηση στην java Απαιτείται αναφορά του Β αντικειμένου σε πεδίο της κλάσης Α (προαιρετικά και το αντίστροφο). Κριτήρια 1) Η ανάγκη διατήρησης γνώσης μεταξύ δύο αντικειμένων για συσχέτιση χρονικού διαστήματος, από χιλιοστά του δευτερολέπτου μέχρι χρόνια. Καλείται επίσης και σχέση «ανάγκης γνώσης». Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 3
2) Η κλάση Α περιλαμβάνει πεδίο-αναφορά της κλάσης Β και αντίστροφα (προαιρετικά) Παράδειγμα Η σχέση Αυτοκινήτου - Ιδιοκτήτη 1) Η κα. Κλεάρχου είναι ιδιοκτήτρια του Αυτοκινήτου ΝΖΡ-2667. 2) Το Αυτοκίνητο ΝΖΡ-2667 ανήκει στην κα Κλεάρχου. UML απεικόνιση Κώδικας class Atomo { private String onoma; private Autokinito exeiauto; public Atomo(String onoma) { this.onoma = onoma; public String getonoma() { return onoma; void setautokinito(autokinito auto) { this.exeiauto = auto; return ("\no k. " + onoma + " einai idioktitis tou autokinitoy " + exeiauto.getarkykloforias()); class Autokinito { Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 4
private String arkykloforias; private Atomo anikeise; // Idioktitis Autokinito(String arkykloforias) { this.arkykloforias = arkykloforias; void setidioktitis(atomo at) { this.anikeise =at; public String getarkykloforias() { return arkykloforias; System.out.println("\nto autikinito me ar. kykloforias " + arkykloforias + " anikei ston " + anikeise.getonoma()); return ""; // Sxesi ASSOCIATION class Association_Demo { public static void main(string argv[]) { Atomo a1 = new Atomo("Klearchou"); Autokinito auto1 = new Autokinito("NZP-2667"); // a1.setautokinito(auto1); auto1.setidioktitis(a1); // System.out.println("Sxesi ASSOCIATION"); System.out.println("-----------------"); System.out.println(a1); System.out.println(auto1); Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 5
Συσχετίσεις «Ολου-Μέρους» (Whole-Part associations) Συναρμολόγηση ή Συγκρότηση (Aggregation) Η συσχέτιση της Συναρμολόγησης είναι είδος της Σύνδεσης, έχει ωστόσο μια επιπλέον σημασία, δηλώνει ότι ένα αντικείμενο Β αποτελεί συστατικό (Μέρος) ενός αντικειμένου της κλάσης Α (Όλο). Μια τέτοιου είδους συσχέτιση αναπαριστά κυρίως την ομαδοποίηση ή ένταξη αντικειμένων-μερών σε ένα άλλο αντικείμενο, το Ολο. Η επικοινωνία μεταξύ του Ολου και του Μέρους στην συναρμολόγηση μπορεί προαιρετικά να είναι και αμφίδρομη. Υλοποίηση στην java Απαιτείται ένας πίνακας-αναφορά στην κλάση Α (Ολο) των αντικειμένων της κλάσης Β (Μέρος). Κριτήρια - Κανόνες Απαντά στο ερώτημα: Είναι μέρος του/της (ομαδοποίηση) Η διατήρηση της γνώσης της συσχέτισης μεταξύ δύο αντικειμένων για κάποιο χρονικό διάστημα, από χιλιοστά του δευτερολέπτου μέχρι χρόνια. Καλείται επίσης και σχέση «ανάγκης γνώσης». Η ανάγκη δημιουργίας αντικειμένου της κλάσης Β από αντικείμενο της κλάσης Α Η κλάση Α περιλαμβάνει πεδίο πίνακα-αναφορών της κλάσης Β. Παράδειγμα Το Ξενοδοχείο «Ακρόπολις» απασχολεί έναν αριθμό Υπαλλήλων (προσωπικό). Ενας από τους Υπαλλήλους ανήκει στον Αθλητικό σύλλογο «Απόλλων». Ενα Ατομο (αντικείμενο) επομένως μπορεί να έχει περισσότερους από έναν ρόλους. Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 6
UML απεικόνιση Κώδικας class Atomo { private String onoma; private String tilephono; public Atomo(String onoma, String tilephono) { this.onoma = onoma; this.tilephono = tilephono; public void setkinito(string tilephono) { this.tilephono = tilephono; return (onoma + " thl. " + tilephono); class Ypallilos { Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 7
private Atomo atomo; private String eidikotita; public Ypallilos(Atomo atomo, String eidikotita) { this.atomo = atomo; this.eidikotita = eidikotita; return ("ypallilos: " + atomo + " Eidkotita: " + eidikotita); import java.util.vector; class Xenodoxeio { private String epwnymia; private Vector <Ypallilow> proswpiko; // πίνακας-αναφορά public Xenodoxeio(String epwnymia) { this.epwnymia = epwnymia; //Αρχικοποιούμε το vector proswpiko = new Vector<Ypallilos>(); public void addypallilos(ypallilos yp) { // AGGREGAION: προσθέτουμε τους Υπαλλήλους proswpiko.add(yp); public String getepwnymia() { return epwnymia; public void printproswpiko() { System.out.println("\nTa proswpiko tou Xenodoxeiou"); if ( proswpiko.isempty() ) System.out.println( "Μήνυμα λάθους." ); else for ( Ypallilos element : proswpiko ) System.out.printf( "%s\n", element.tostring() ); import java.util.vector; class AthlitikosSyllogos { Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 8
private String epwnymia; private Vector<Paiktis> paiktes; public AthlitikosSyllogos(String epwnymia) { this.epwnymia = epwnymia; paiktes = new Vector<Paiktis>(); public String getepwnymia() { return epwnymia; public void addpaiktis(paiktis paiktis) { // AGGREGAION: prosthetoyme atoma - paiktes stin Omada paiktes.add(paiktis); public void printsyllogos() { System.out.println("\nAthlitikos syllogos: " + epwnymia); System.out.println("--------------------------------------"); if ( paiktes.isempty() ) System.out.println( "..." ); else for ( Paiktis element : paiktes ) System.out.printf( "%s\n", element.tostring() ); class Paiktis { private Atomo atomo; private String katigoria; public Paiktis(Atomo atomo, String katigoria) { this.atomo = atomo; this.katigoria = katigoria; return ("paiktis: " + atomo + " katigoria: " + katigoria); // Sxesi Whole-Part associations // 1) Aggregation // 2) Composition Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 9
public class WholePart _Demo { public static void main(string[] argv) { Xenodoxeio x = new Xenodoxeio("Akropolis"); x.printdwmatia(); Atomo at1 = new Atomo("Dimitriou", "6945777444"); Ypallilos yp1 = new Ypallilos(at1, "Mageiras"); x.addypallilos(yp1); Atomo at2 = new Atomo("Xeimwnidis", "6967888222"); Ypallilos yp2 = new Ypallilos(at2, "Logistis"); x.addypallilos(yp2); // Emfanizei to proswpiko x.printproswpiko(); // Dimiourgeitai h Omada AthlitikosSyllogos apollwn = new AthlitikosSyllogos("APOLLWN"); Paiktis p1 = new Paiktis(at2, "Termatofylakas"); apollwn.addpaiktis(p1); // Emfanizei thn Omada apollwn.printsyllogos(); // o Xeimwnidis allazei arithmo tilephonou at2.setkinito("6944333000"); // Emfanisi meta thn allagi stoixeiwn toy Xeimwnidi System.out.println("\n\nEmfanisi meta thn allagi stoixeiwn toy Xeimwnidi"); x.printproswpiko(); apollwn.printsyllogos(); Σύνθεση (Composition) Η συσχέτιση της Σύνθεσης ανήκει και αυτή στην κατηγορία «Ολου-Μέρους», και αποτελεί ειδική περίπτωση της Συναρμολόγησης, επιβάλλοντας περαιτέρω περιορισμούς. Στη Σύνθεση το Ολο κατέχει αποκλειστικά τα Μέρη του, γι αυτό χαρακτηρίζεται και ως ισχυρή συσχέτιση. Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 10
Η επικοινωνία μεταξύ του Ολου και του Μέρους είναι μονόδρομη. Η επικοινωνία με τα μέρη δεν είναι εφικτή παρά μόνο μέσω του Ολου. Υλοποίηση στην java Απαιτείται πίνακα-αναφορά αντικειμένων του Β στα πεδία της κλάσης Α. Ολα τα αντικείμενα, του Ολου και των Μερών δημιουργούνται ταυτόχρονα. Τα αντικείμενα των μερών δημιουργούνται μέσα στον δημιουργό (constructor) του Α. Κριτήρια - Κανόνες Απαντά στο ερώτημα: Είναι μέρος του/της Το Μέρος ανήκει αποκλειστικά στο Ολο (ιδιοκτησία). Δεν επιτρέπεται η συμμετοχή του Μέρους σε άλλες ομάδες αντικειμένων. Το Ολο γνωρίζει τα Μέρη του και επομένως μπορεί να επικοινωνεί μαζί τους, ενώ τα Μέρη δεν γνωρίζουν το Ολο στο οποίο ανήκουν, άρα δεν επικοινωνούν (μονόδρομη επικοινωνία). Η διάρκεια ζωής του Μέρους είναι άρρηκτα συνδεδεμένη με εκείνη του Ολου. Υπάρχει δηλαδή εξάρτηση δημιουργίας-καταστροφής μεταξύ Ολου και Μέρους. Μερικές ιδιότητες μεταδίδονται από το Ολο στο Μέρος, όπως αυτή της τοποθεσίας. Λειτουργίες που εφαρμόζονται στο Ολο μεταδίδονται και στα Μέρη του, όπως η καταστροφή, η μετακίνηση, η εγγραφή. Η επικοινωνία με το Μέρος γίνεται μόνο μέσω του Ολου. Παράδειγμα Το Ξενοδοχείο «Ακρόπολις» διαθέτει έναν αριθμό δωματίων. UML απεικόνιση: με γεμάτο ρόμβο (βλ. προηγούμενο διάγραμμα) Κώδικας class Dwmatio { private String kodikos; Dwmatio(String kodikos) { this.kodikos = kodikos; return ("dwmatio me kodiko: " + kodikos); import java.util.vector; class Xenodoxeio { private String epwnymia; Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 11
private Vector<Dwmatio> dwmatia; // anafora se pinaka antikeimeno public Xenodoxeio(String epwnymia) { this.epwnymia = epwnymia; //Arxikopoioume ta vector dwmatia = new Vector<Dwmatio>(); // COMPOSITION: Dimiourgountai ta dwmatia tautoxrona me thn // dimiourgia tou Xenodoxeiou Dwmatio a1 = new Dwmatio("Diklino A1"); Dwmatio s1 = new Dwmatio("Sudio S1"); Dwmatio d1 = new Dwmatio("Diamerisma D1"); dwmatia.add(a1); dwmatia.add(s1); dwmatia.add(d1); public void addypallilos(ypallilos yp) { // AGGREGAION: prosthetoyme Ypallilous oi opoioi omws mporoun na // anhkoun kai se alli Omada (px. Volley). proswpiko.add(yp); public String getepwnymia() { return epwnymia; public void printdwmatia() { System.out.println("Ta dwmatia tou Xenodoxeiou"); if ( dwmatia.isempty() ) System.out.println( "..." ); else for ( Dwmatio element : dwmatia ) System.out.printf( "%s\n", element.tostring() ); // Sxesi Whole-Part associations // 1) Aggregation // 2) Composition public class WholePart { public static void main(string[] argv) { Xenodoxeio x = new Xenodoxeio("Akropolis"); x.printdwmatia(); Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 12
Γενίκευση - Ειδίκευση (Generalization - Specification) Η συσχέτιση της Γενίκευσης-Ειδίκευσης, σε αντίθεση με τις προηγούμενες βασίζεται στις κλάσεις (class-based). Απώτερος σκοπός είναι η επίτευξη μεγαλύτερου βαθμού επαναχρησιμοποίησης. Συνεπώς, μέλη (πεδία, μέθοδοι, και συσχετίσεις) που δηλώνονται σε μια κλάση (υπερκλάση), κληρονομούνται από τις υποκλάσεις της μέσω του μηχανισμού της Κληρονομικότητας, οι οποίες έτσι εκμεταλλεύονται πλήρως την κληρονομούμενη λειτουργικότητα της υπερκλάσης. Κριτήρια - Κανόνες Απαντά στην ερώτηση: η κλάση Β είναι είδος της κλάσης Α; Κληρονομούνται δίχως εξαίρεση το 100% των μελών (πεδία, μέθοδοι, και συσχετίσεις) της υπερκλάσης. Σε περίπτωση διαφορετικής υλοποίησης μιας κληρονομούμενης μεθόδου, τότε αυτή επαναϋλοποιείται (υπέρβαση - overriding) στην υποκλάση. Δεν επιτρέπεται ωστόσο κατάχρηση της επαναϋλοποίησης με κενή από κώδικα μέθοδο, η οποία ουσιαστικά ακυρώνει την λειτουργικότητα της υποκλάσης. Παράδειγμα Το Επιβατικό IX αυτοκίνητο είναι είδος Οχήματος UML απεικόνιση: με γραμμή που στην μία άκρη φέρει τρίγωνο Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 13
Κώδικας class Atomo { private String onoma; public Atomo(String onoma) { this.onoma = onoma; public String getonoma() { return onoma; return (" onoma " + onoma); abstract class Oxima { private String arkykloforias; private String marka; private Atomo idioktitis; Oxima(String arkykloforias, String marka) { this.arkykloforias = arkykloforias; this.marka = marka; public String getarkykloforias() { return arkykloforias; public String getmarka() { return marka; public void setidioktitis(atomo idiokt) { this.idioktitis = idiokt; return ("to autikinito me ar. kykloforias " + arkykloforias + " einai " + marka + " anikei sto/in " + idioktitis); Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 14
class IX extends Oxima { private String eidos; private int arthesewn; IX(String arkykloforias, String marka, String eidos, int arthesewn) { super(arkykloforias, marka); this.eidos = eidos; this.arthesewn = arthesewn; return (super.tostring() + " einai " + eidos + " thesewn " + arthesewn); // Sxesi INHERITANCE class Inheritance_Demo { public static void main(string argv[]) { Atomo at = new Atomo("Klearchou Elpiniki"); IX ix = new IX("NZP-1234", "Alfa Romeo", "IX 4-thyro", 5); ix.setidioktitis(at); System.out.println(ix); Ιγνάτιος Δεληγιάννης, Κ-Σ ΕΑΠ, ΠΛΗ24 15