Σάββατο 2 Σεπτεμβρίου 2017

Χρήση Αντικειμένου Ομάδα (απόσπασμα)


Απόσπασμα από το βιβλίο:

Αναθεώρηση κειμένου έως έκδοση 9.3 αναθ. 22

Προγραμματίζοντας με τη Μ2000

Γενικά Περί Σχεδιασμού των Ομάδων

Στην γλώσσα Μ2000 τα αντικείμενα τύπου ομάδα λειτουργούν ως Πρότυπα και Αντικείμενα μαζί. Πριν ξεκαθαρίσουμε τι είναι το αντικείμενο ομάδα, θα δούμε τα τρία στάδια ανάπτυξης των ομάδων στην Μ2000.



Στο αρχικό στάδιο σχεδιασμού ένα αντικείμενο τύπου Group (Ομάδα) περιείχε μόνο μια λίστα αναγνωριστικών για μεταβλητές και τμήματα και συναρτήσεις, αυτή θα τη λέμε λίστα μελών. Μπορούσαμε να περάσουμε με αναφορά την ομάδα σε ένα τμήμα και βάσει της λίστας "μελών" ο διερμηνευτής δημιουργούσε νέες μεταβλητές και τμήματα και συναρτήσεις με αναφορά σε αυτά. Από τον αρχικό σχεδιασμό μια ομάδα μπορούσε να συμπεριλάβει όλους τους τύπους μεταβλητών, πίνακες καθώς και άλλες ομάδες ως μέλη της.



Στο επόμενο στάδιο ανάπτυξης καθιερώθηκε η διαφορά κλειστού και ανοικτού αντικειμένου. Ανοικτό αντικείμενο είναι η ομάδα που έχει άμεσα διαθέσιμα τα μέλη της στο σύστημα. Κλειστό αντικείμενο είναι η ομάδα που διαθέτει όχι μόνο αναφορές στα μέλη της, αλλά και τις τιμές τους και δεν τις παρέχει στο σύστημα.



Επειδή στη Μ2000 η εκχώρηση χρησιμοποιείται και για δημιουργία (όταν δίνουμε νέο όνομα), σε αυτό το στάδιο η εκχώρηση ομάδας σε νέο όνομα σήμαινε την παραγωγή ενός νέου κλειστού αντικειμένου (από το αντικείμενο της δεξιάς έκφρασης, δηλαδή δεξιά του ίσον), και κατόπιν άνοιγμα του κλειστού αντικειμένου με το νέο όνομα, και τελικά απόρριψη του κλειστού αντικειμένου.



Σε περίπτωση εκχώρησης σε υπάρχουσα ομάδα χρησιμοποιήθηκε η λεγόμενη λειτουργία της συγχώνευσης, ή απλά συγχώνευση, όπου σε μέλη που υπάρχουν τόσο στο κλειστό αντικείμενο (σε αυτό που προκύπτει από την δεξιά έκφραση) όσο και στο ανοιχτό της αριστερής έκφρασης, έχουμε εκχώρηση τιμής από δεξιά προς αριστερά, ενώ αν έχουμε νέο μέλος, δηλαδή μέλος στο κλειστό αντικείμενο που δεν υπάρχει στο ανοικτό (αριστερά) τότε δημιουργείται αντίγραφο.



Τρίτη και σημαντική λειτουργία του κλειστού αντικειμένου (πάντα στο δεύτερο στάδιο ανάπτυξης των ομάδων), ήταν η καταχώρηση κλειστών αντικειμένων σε θέσεις μνήμης, αρχικά σε πίνακες και στο σωρό τιμών, καθώς και ως επιστροφή τιμής από συνάρτηση, και το οποίο επεκτάθηκε σε αντικείμενα Καταστάσεις και Σωρούς. Δυο πράγματα εδώ έχουν σημασία, ότι δεν αφήνει η Μ2000 να έχουμε πολλαπλούς δείκτες προς ομάδες, άρα μια ομάδα δεν μπορεί να βρίσκεται σε δυο ξεχωριστές θέσεις, και αυτό ως συνέπεια σημαίνει ότι μια ομάδα δεν μπορεί να περιέχει τον εαυτό της! Μια εκχώρηση ομάδας σε μια θέση σημαίνει διαγραφή της υπάρχουσας ομάδας (αφού δεν υπάρχει άλλος δείκτης να την κρατάει εν ζωή).


Συμπλήρωση:
1. Ελαφριά γεγονότα
Από την 9η έκδοση μπορούμε να φτιάχνουμε "ελαφριά" γεγονότα. Ενώ μέχρι πριν μπορούσαμε να έχουμε ένα αντικείμενο γεγονός και σε αυτό να βάζαμε συναρτήσεις (ακόμα και συναρτήσεις από επώνυμες ομάδες, δηλαδή ανοικτές ομάδες), έτσι ώστε να είχαμε μια multicast, η πολλαπλή κλήση συναρτήσεων εξυπηρέτησης ανά γεγονός (βάσει μιας υπογραφής παραμέτρων), τώρα έχουμε το πλεονέκτημα να φτιάχνουμε ομάδες με χαρακτηριστικό ΜεΓεγονότα, όπου η επώνυμη ομάδα, δημιουργεί μια λίστα συναρτήσεων, μια για κάθε γεγονός, χωρίς να εξετάζει τις παραμέτρους, και όταν καλούμε το γεγονός μέσα από το αντικείμενο τότε αυτό μπορεί να εκτελεστεί αν έχουμε δώσει μια συνάρτηση με το όνομα της ομάδας μια κάτω παύλα και το όνομα του γεγονότος (όπως η εσωτερική λίστα τα έχει καταγεγραμμένα, ακόμα και αν δεν υπάρχουν). Όταν ένα αντικείμενο με γεγονότα περνάει με αναφορά κάπου, τότε τα γεγονότα θα κληθούν κανονικά. Οι συναρτήσεις εξυπηρέτησης δουλεύουν όπως και στα γεγονότα για τις φόρμες (Παράθυρα), δηλαδή καλούνται τοπικά, έτσι ώστε να υπάρχει θέαση μεταβλητών στο τμήμα, με τη διαφορά ότι έχουμε νέο σωρό τιμών (δεν έχουμε πρόσβαση στο σωρό τιμών και στις στατικές του τμήματος).

2. Δείκτες σε Ομάδες
Από την έκδοση 9 μπορούμε να φτιάχνουμε δείκτες για ομάδες. Έτσι αν μας ενδιαφέρει αυτό, μπορούμε μια κλειστή ομάδα να υπάρχει απλά ως δείκτης κάπου, σε μια άλλη κλειστή ομάδα, σε μια μεταβλητή, σε μια θέση σε έναν καταχωρητή, όπως πίνακα, κατάσταση ή σωρό. Οι δείκτες δουλεύουν και για τις ανοικτές ομάδες, ως αναφορές στις ομάδες. Οι δείκτες μπορούν να αλλάξουν, να δείχνουν σε άλλη ομάδα, κλειστή ή ανοιχτή, και μπορούν να πάρουν μηδενική τιμή, δηλαδή να μην δείχνουν τίποτα.


Συμπλήρωση: η διαγραφή γίνεται στο κλειστό αντικείμενο στη θέση προορισμού, έτσι αν εκχωρήσουμε ένα ανοικτό σε μια θέση πίνακα τιμών, τότε πρώτα βγαίνει ένα αντίγραφο ως κλειστό αντικείμενο και παίρνει τη θέση στο πίνακα τιμών, ενώ το τυχόν παλιό αντικείμενο διαγράφεται σίγουρα, αφού μόνο ένας δείκτης δείχνει μια κλειστή ομάδα

Α(4)=Ομάδα1
Α(4)=Ομάδα2

Τα Ομάδα1 και Ομάδα2 είναι ανοικτά αντικείμενα (έχουν όνομα)
Το Α(4) είναι κλειστό αντικείμενο, έχει θέση, το 4 σε ένα πίνακα Α()

Αν η Ομάδα1 έχει την μεταβλητή Χ θα την έχει και το Α(4), και θα συνεχίσει να την έχει αν την έχει και η Ομάδα2 που θα μπει μετά!
Μπορούμε να χρησιμοποιήσουμε τα κλειστά αντικείμενα άμεσα:

Τύπωσε Α(4).Χ
Α(4).Χ+=100

Αν εκχωρήσουμε κλειστό αντικείμενο σε κλειστό, δηλαδή το Α(4)=Β(6) όπου το Α(4) είχε ένα κλειστό αντικείμενο, όπως και το Β(6) τότε θα δημιουργηθεί ένα νέο κλειστό αντικείμενο από το Β(6), και θα μεταγραφεί στο Α(4), έτσι το αντικείμενο που υπήρχε στο Α(4) θα διαγραφεί. Τώρα το Α(4) έχει αντίγραφο του Β(6).



Ο χειρισμός των ομάδων σε θέσεις γίνεται αυτόματα, με άνοιγμα όταν χρειάζεται, εκτέλεση, και κλείσιμο. Κατά το άνοιγμα η ομάδα βάζει τα μέλη της στο σύστημα, με όνομα αυτόματα, και στην επιστροφή δημιουργείται ένα κλειστό αντικείμενο που διαγράφει το παλιό.
Στο τρίτο στάδιο ανάπτυξης οι ομάδες απόκτησαν δυνατότητα να γυρνούν τιμές και να δέχονται τιμές, ώστε αντί να εκχωρούμε στην ομάδα άλλη προς συγχώνευση να εκχωρούμε τιμή η οποία οδηγείται σε ένα μέλος Θέσε (είναι συνάρτηση) εντός της ομάδας. Επίσης δόθηκε η δυνατότητα να αποδίδει αξία μια ομάδα, μέσω του μέλους Αξία (είναι συνάρτηση). Καθιερώθηκαν τρία μέρη (μπορούμε να τα εναλλάσσουμε, δεν έχει νόημα η σειρά και ο αριθμός εμφάνισης, εκτός αν είναι κάτι προαπαιτούμενο), το δημόσιο, το ιδιωτικό και η κλάση. Το πρώτο ορίζει τι θα είναι ορατό έξω από το αντικείμενο, το δεύτερο τι θα είναι ορατό μόνο για τα τμήματα και τις συναρτήσεις της ομάδας, και το τελευταίο τι θα είναι ορατό και θα υπάρχει μόνο στο ανοικτό αντικείμενο. Ειδικά το τρίτο, η κλάση, χρησιμοποιείται για να δημιουργούμε νέα αντικείμενα με κώδικα που δεν θα περιέχεται σε αυτά.



Με την λέξη πρότυπο εννοούμε ότι ένα υπάρχον αντικείμενο μπορεί να δημιουργήσει ένα δεύτερο αντικείμενο, όπως τη δεδομένη στιγμή έχει διαμορφωθεί, και κατόπιν τόσο το πρώτο όσο και το δεύτερο (το παραγόμενο) δύναται να αλλάξουν. Όπως είδαμε γίνεται ένα αντικείμενο να περιέχει μέρη που δεν θα τα δώσει στο νέο αντικείμενο, επειδή ορίζονται μετά την ετικέτα ΚΛΑΣΗ: και έχουμε βέβαια τους λόγους μας.



Όπως η εντολή Συνάρτηση δημιουργεί συναρτήσεις, και η εντολή Κλάση δημιουργεί συναρτήσεις οι οποίες επιστρέφουν αντικείμενο (κλειστό αντικείμενο). Μέσα σε ορισμούς ομάδων μπορούμε να έχουμε μέλη Κλάσεις, για να δημιουργούμε αντικείμενα, ή να έχουμε αντικείμενα και από αυτά θα δημιουργούμε άλλα. Η διαφορά είναι ότι τα μέλη Κλάσεις, πρώτα δημιουργούν ένα ανοικτό αντικείμενο και μετά καλούν τον κατασκευαστή (με ίδιο όνομα), για να το τροποποιήσει, και τέλος επιστρέφουν το κλειστό αντικείμενο με απορρίψεις τυχόν πρόσθετου κώδικα που χαρακτηρίζεται ως κώδικας Κλάσης.

Απλή Ομάδα



Μια απλή ομάδα είναι η επώνυμη ομάδα, η οποία ταυτίζεται με το πρώτο στάδιο ανάπτυξης. 
Μπορεί να γραφτεί σε ένα τμήμα. Θα υπάρχει όσο το τμήμα υπάρχει. Με το πέρας εκτέλεσης του τμήματος, η ομάδα καταστρέφεται. Μπορούμε όμως πριν τερματίσει το τμήμα να βάλουμε ένα αντίγραφο (ένα κλειστό αντικείμενο) στο σωρό!

Δημιουργία Ομάδας

Μια ομάδα μπορεί να έχει δυο μέλη τα Χ και Υ ως συντεταγμένες ενός αντικειμένου σχεδίασης. Ας δεχτούμε εδώ ότι το αντικείμενο είναι ένα απλό σημείο.
Ομάδα Ένα_Σημείο {
      Χ=10, Υ=20
      Τμήμα Νέες_Τιμές (, ) {}
      ' Τμήμα Νέες_Τιμές { Διάβασε .Χ, .Υ }
}
Τύπωσε Ένα_Σημείο.Χ, Ένα_Σημείο.Υ
Ένα_Σημείο.Νέες_Τιμές 100, 500
Τύπωσε Ένα_Σημείο.Χ, Ένα_Σημείο.Υ


Όπως φαίνεται, στο παράδειγμα πάνω, η ομάδα Ένα_Σημείο έχει τρία μέλη, δυο μεταβλητές, τα Χ και Υ και ένα τμήμα το Νέες_Τιμές. Στο κώδικα φαίνεται με πλάγια γράμματα το πώς φτιάχνεται το τμήμα Νέες_Τιμές, όπου μπαίνει μια Διάβασε .Χ, .Υ
Πρώτα δημιουργούμε την επώνυμη ομάδα με τη χρήση της εντολής Ομάδα, δηλαδή χωρίς χρήση προτύπου. Μετά εμφανίζουμε τις τιμές των μεταβλητών Χ και Υ. Μετά εκτελούμε το τμήμα με νέες τιμές για τα Χ και Υ και τέλος βλέπουμε τις αλλαγές.
Μια παραλλαγή εδώ:
Για Ένα_Σημείο {
      Τύπωσε .Χ,
      .Νέες_Τιμές 200, 1500
      Τύπωσε .Χ,
}


Η Για αντικείμενο {} δημιουργεί ένα μπλοκ πρόσκαιρων ορισμών. Εδώ δεν κάνουμε κάτι νέο, τα Χ και Υ ήδη υπάρχουν, όπως και το τμήμα Νέες_Τιμές, αλλά όλα με το πλήρες όνομά τους (έχουν επιπλέον και το μη φανερό πρόθεμα, το όνομα του τμήματος που περιέχονται και τη δεδομένη στιγμή είναι σε εκτέλεση)


Επέκταση Ομάδας

Μπορούμε να προσθέσουμε μια λειτουργία σε ένα ανοικτό αντικείμενο τύπου Ομάδα. Εδώ θα προσθέσουμε ένα τμήμα και θα το χρησιμοποιήσουμε:
Ομάδα Ένα_Σημείο {
      Τμήμα Χ2 {
            ++
      }
}
Για Ένα_Σημείο {
      .Χ2
      .Χ2
      Τύπωσε .Χ
}


Δεν έχει προβλεφθεί η διαγραφή μέλους σε ομάδες. Όμως εκ των πραγμάτων γίνεται να διαγραφεί μέλος σε μια πρόσκαιρη ομάδα που δημιουργήθηκε από μια υπάρχουσα, με αναφορά, και σε αυτή δημιουργήσαμε νέα μέλη (τα οποία δεν καταχωρήθηκαν στην αρχική ή αναφερόμενη ομάδα).
 

Δημιουργία από Πρότυπο

Εκτός από τη δημιουργία/Επέκταση ομάδας με την εντολή Ομάδα, μπορούμε να φτιάχνουμε ομάδες από κλειστά αντικείμενα, όταν έχουμε νέα ονόματα, ή να κάνουμε συγχωνεύσεις όταν έχουμε ονόματα ομάδων (αν έχουμε όνομα με κάτι άλλο, τότε βγάζει λάθος ο διερμηνευτής κατά την εκτέλεση).
Άλλο=Ένα_Σημείο
Ένα_Σημείο.Χ2
Άλλο_Ένα=Ένα_Σημείο
Τύπωσε Άλλο_Ένα.Χ-Άλλο.Χ


Η διαφορά Άλλο_Ένα.Χ-Άλλο.Χ είναι 1
Άλλο_Ένα=Άλλο
Τύπωσε Άλλο_Ένα.Χ-Άλλο.Χ


Τώρα η διαφορά είναι 0 γιατί κάναμε συγχώνευση (Εδώ φάνηκε ως εκχώρηση), αλλά παρακάτω θα δούμε πως σε υπάρχουσα ομάδα θα συγχωνεύσουμε μια άλλη.

Θα φτιάξουμε μια ομάδα για να το χρησιμοποιούμε ως πρότυπο, και μετά θα φτιάξουμε δυο ομάδες, σε δυο φάσεις. Στη πρώτη φάση η ομάδα θα γίνει ίδια με το πρότυπο (με αντιγραφή), και στη δεύτερη θα κάνει συγχώνευση από άλλη ομάδα. Και στις δυο περιπτώσεις τα Χ και Υ αναφέρονται ως ονόματα και ο διερμηνευτής τα βρίσκει κατά την εκτέλεση του τμήματος Όλα.
Ομάδα Τελική1 {
      Τμήμα Όλα {
            Τύπωσε .Χ,
      }
}
Τελική=Τελική1
Τελική=Άλλο_Ένα
Άλλο.Χ2
Τελική_Άλλη=Τελική1
Τελική_Άλλη=Άλλο
Τελική.Όλα
Τελική_Άλλη.Όλα

Στο προηγούμενο παράδειγμα, το Άλλο συγχωνεύτηκε στο Τελική_Άλλη. Η συγχώνευση γίνεται με αντιγραφή, δηλαδή το Άλλο παραμένει ως ομάδα που δεν περιέχεται στο Τελική_Άλλη. Αυτό σημαίνει ότι αν εκτελέσουμε το τμήμα Χ2 με μια εντολή Άλλο.Χ2 θα αυξηθεί το Άλλο.Χ κατά ένα, και όχι το Τελική_Άλλη.Χ κατά ένα. Για να αυξήσουμε το Τελική_Άλλη.Χ κατά ένα μπορούμε να χρησιμοποιήσουμε το Τελική_Άλλη.Χ2 ή χωρίς χρήση τμήματος, επειδή η Χ είναι μεταβλητή: Τελική_Άλλη.Χ++ (το ++αυξάνει κατά ένα το Τελική_Άλλη.Χ)
Από τα παραπάνω βλέπουμε ότι δυο πράγματα θεωρούνται τροποποιήσεις σε μια ομάδα: Η αλλαγή τιμής σε ένα τουλάχιστον μέλος και η προσθήκη μέλους. Σε μια συγχώνευση μπορεί να συμβαίνει ένα από τα δυο ή και τα δύο. Αν συμβαίνει η αλλαγή τιμής μόνο και η τιμή είναι ίδια, τότε δεν έχουμε στην ουσία τροποποίηση. Δείτε τι γίνεται εδώ:

Η εντολή Άλλο = Άλλο θα δημιουργήσει ένα κλειστό αντικείμενο από το Άλλο (όπως το βρίσκει ο διερμηνευτής στα δεξιά του ίσον) και από αυτά θα γίνει συγχώνευση με αντιγραφή τιμής σε όλα τα μέλη (ακόμα και στις συναρτήσεις/τμήματα) σε αυτό που είναι αριστερά του ίσον (στο ανοικτό αντικείμενο). Έτσι ουσιαστικά όταν θα γίνει η συγχώνευση θα υπάρχουν δυο αντικείμενα, το κλειστό ως αντίγραφο του Άλλο και το Άλλο ως ανοικτό αντικείμενο.

 

Πέρασμα Ομάδας


Όπως αναφέρθηκε στα γενικά περί ομάδων η πρώτη ιδέα για την χρήση των ομάδων ήταν το πέρασμα της ομάδας ως όρισμα σε κλήση τμήματος ή συνάρτησης.


Στο παράδειγμα που ακολουθεί θα φτιάξουμε μια Κλάση, δηλαδή μια συνάρτηση που επιστρέφει ομάδα (ένα κλειστό αντικείμενο), και σε αυτό δεν θα βρίσκεται το τμήμα κατασκευής, δηλαδή το τμήμα που περνάει τιμές στα Χ και Υ:
Κλάση Ένα_Σημείο {
      Χ, Υ
Κλάση:
      Τμήμα Ένα_Σημείο (, ) {}
}
Κ=Ένα_Σημείο(100,200)
Λ=Ένα_Σημείο(450,400)
Μ=Ένα_Σημείο(200, 500)
Τμήμα Τρίγωνο {
      Διάβασε Κ1, Κ2, Κ3, Π
      Για Κ1, Κ2, Κ3 {
            Θέση .Χ*Π,*Π
            Χαραξε Εως ..Χ*Π,..Υ*Π
            Χαραξε Εως ...Χ*Π,...Υ*Π
            Χαραξε Εως*Π,*Π
      }
}
Τρίγωνο Κ, Λ, Μ, 15

Το τμήμα Τρίγωνο δέχεται τέσσερα ορίσματα. Τα τρία πρώτα περιμένει να είναι ομάδες με μέλη τα Χ και Υ και τελευταίο να είναι ένας αριθμός, ένας πολλαπλασιαστής. Προσέξτε τη χρήση της Για και τον αριθμό των τελειών όπου η μια τελεία σχετίζεται με το Κ1, οι δυο τελείες με το Κ2 και οι τρεις με το Κ3. Όταν καλούμε το Τρίγωνο δημιουργείται νέο αντικείμενο εκτέλεσης και σε αυτό έχουν νόημα οι τελείες (και ο αριθμός τους).
Το πέρασμα των ορισμάτων εδώ στο παράδειγμα γίνεται με τιμή. Αυτό σημαίνει ότι τα Κ, Λ, Μ έχουν γίνει κλειστά αντικείμενα (άρα αντίγραφα των ανοικτών) και έχουν μπει στο σωρό τιμών. Στο τμήμα Τρίγωνο η εντολή Διάβασε βρίσκει ότι το Κ1 δεν υπάρχει και βρίσκει ότι η πρώτη τιμή στο σωρό (στη κορυφή όπως λέμε) είναι ένα κλειστό αντικείμενο, και εφαρμόζει αυτό που γνωρίζει, δηλαδή δημιουργεί ένα ανοικτό αντικείμενο Κ1 από το κλειστό που βρήκε, το δε κλειστό το πετάει πριν διαβάσει το Κ2 και βρει το επόμενο κλειστό αντικείμενο! Έτσι ουσιαστικά περάσαμε το Κ στο Κ1 χωρίς το Κ να μπορεί να τροποποιηθεί από το τμήμα Τρίγωνο.



Θα τροποποιήσουμε το παράδειγμα με το τρίγωνο και θα προσθέσουμε ένα τμήμα στο τμήμα Τρίγωνο το οποίο θα προετοιμάζει τα Χ και Υ πριν τα χρησιμοποιήσουμε με τις εντολές γραφικών. Θα δουλέψουμε με το πέρασμα με αναφορά.



Αρχικά θα δούμε μια απλή ανάπτυξη:
Κλάση Ένα_Σημείο {
      Χ, Υ
Κλάση:
      Τμήμα Ένα_Σημείο (, ) {}
}
Κ=Ένα_Σημείο(100,200)
Λ=Ένα_Σημείο(450,400)
Μ=Ένα_Σημείο(200, 500)
Τμήμα Τρίγωνο {
      Διάβασε Κ1, Κ2, Κ3, Π
      Τμήμα Χ2 {
            Διάβασε, Π1
            Για Κ {
                  *=Π1
                  *=Π1
            }
      }
      Χ2 &Κ1, Π
      Χ2 &Κ2, Π
      Χ2 &Κ3, Π
      Για Κ1, Κ2, Κ3 {
            Θέση .Χ,
            Χαραξε Εως ..Χ,..Υ
            Χαραξε Εως ...Χ,...Υ
            Χαραξε Εως,
      }
}
Τρίγωνο Κ, Λ, Μ, 15


Δείτε ότι το τμήμα Τρίγωνο έχει και δικό του τμήμα, το Χ2. Αυτό το τμήμα θα υπάρχει όταν εκτελεστεί η εντολή Τμήμα Χ2 {} στο τμήμα Τρίγωνο και θα εξαφανιστεί όταν τερματίσει το τμήμα Τρίγωνο. Όσο το τμήμα Χ2 δεν εκτελείται δεν υπάρχουν μεταβλητές γι' αυτό. Όμως εδώ αμέσως μετά τον ορισμό το καλούμε τρεις φορές. Και σε κάθε περίπτωση περνάμε με το χαρακτήρα & στην αρχή τα Κ1, Κ2 και Κ3 διαδοχικά. Σε κάθε περίπτωση περνάμε και την τιμή Π με την οποία θέλουμε να πολλαπλασιάσουμε τα Χ και Υ (δεν μας πειράζει να μείνουν ως γινόμενα παλιάς τιμής με το Π γιατί έχουμε περάσει με τιμή τα Κ, Λ και Μ άρα σε αυτά δεν θα υπάρξει κάποια αλλαγή. Το κέρδος μας από την χρήση του Χ2 είναι στο ότι έχουμε τελικές τιμές στα Κ1, Κ2 και Κ3. Το πέρασμα με αναφορά άλλαξε τις τιμές των Χ και Υ στα Κ1, Κ2 και Κ3. Για να ολοκληρώσουμε το τρίγωνο χαράζουμε προς το αρχικό σημείο, όπου τώρα δεν χρειάζεται να γίνει υπολογισμός γινομένου, γιατί τον έχουμε ήδη!
Εδώ υπάρχει ακόμα ένα θέμα που μας απασχολεί: Υπάρχει κρυφό αντικείμενο;



Το τμήμα Τρίγωνο φαντάζει σαν να είναι ένα αντικείμενο! Διότι υπάρχει όπως υπάρχει μια ομάδα, όσο τρέχει αυτό που το δημιούργησε, και μπορεί να έχει μεταβλητές και τμήματα. Όμως υπάρχει μια ουσιαστική διαφορά. Το τμήμα τρίγωνο έχει μεταβλητές την ώρα της εκτέλεσης, και έχει δικά του τμήματα την ώρα της εκτέλεσης. Μια ομάδα έχει μεταβλητές "ομάδας", ως μέλη της ομάδας δηλαδή, κατά τη δημιουργία, ή κατά την επέκταση, και μπορεί να "κλειστεί" δηλαδή να μπει σε μια θέση, όπου δεν θα εκτελείται, αλλά θα βρίσκεται σε αναμονή, με έτοιμες συναρτήσεις-τμήματα και μεταβλητές. Όπως όταν καλέσαμε το Τρίγωνο και βάλαμε στο σωρό τιμών τα Κ, Λ και Μ.



Ας δούμε μια τροποποίηση του κώδικα του τμήματος Τρίγωνο. Θα βγάλουμε την παράμετρο Π και θα δουλέψουμε απ' ευθείας με το σωρό τιμών. Βελτιώνουμε την ταχύτητα σε βάρος της ανάγνωσης του κώδικα:

Τμήμα Τρίγωνο {
      Διάβασε Κ1, Κ2, Κ3
      Πάνω 1, 2
      Τμήμα Χ2 {
            Διάβασε
            Πάνω
            Για Κ {
                  *=Αριθμός
                  *=Αριθμός
            }
      }
      Χ2 &Κ1
      Χ2 &Κ2
      Χ2 &Κ3
      Για Κ1, Κ2, Κ3 {
            Θέση .Χ,
            Χαραξε Εως ..Χ,..Υ
            Χαραξε Εως ...Χ,...Υ
            Χαραξε Εως,
      }
}
Τρίγωνο Κ, Λ, Μ, 15

Το 15 πάει ως τέταρτο όρισμα. Η εντολή Διάβασε αφήνει το 15 στη κορυφή του σωρού. Η Πάνω 1,2 παίρνει το 1ο στοιχείο (την κορυφή) και την αντιγράφει σε μια νέα πρώτη θέση δυο φορές. Έτσι έχουμε το 15 τρεις φορές στις πρώτες θέσεις του σωρού. Όταν καλούμε το Χ2 τότε βάζουμε την αναφορά στο Κ1 σωρό (είναι αλφαριθμητικό στο σωρό και λέγεται ισχνή αναφορά, και την επιλύει η Διάβασε) και το Χ2 κληρονομεί το σωρό του πατρικού, άρα μετά το διάβασμα του &Κ (όπου φτιάχνει τα Κ.Χ και Κ.Υ ως αναφορές στο Κ1, μετά στο Κ2 κ.ο.κ.) θα υπάρχει σίγουρα το 15, το οποίο το θέλουμε δυο φορές και μια σκέτη εντολή Πάνω (ισοδυναμεί με το Πάνω 1, 1) θα βγάλει ένα δεύτερο 15. Τα δυο αυτά 15άρια θα βγουν από το σωρό με το διάβασμα με την Αριθμός.
Η δύναμη στον προγραμματισμό με αντικείμενα φαίνεται όταν πάρουμε ένα κώδικα που "Φάνταζε" αντικείμενο και το μετατρέψουμε σε αντικείμενο:

Κλάση Ένα_Σημείο {
      Χ, Υ
Κλάση:
      Τμήμα Ένα_Σημείο (, ) {}
}
Κ=Ένα_Σημείο(100,200)
Λ=Ένα_Σημείο(450,400)
Μ=Ένα_Σημείο(200, 500)
Κλάση Τρίγωνο {
      Κ1=Ένα_Σημείο(0,0)
      Κ2=Ένα_Σημείο(0,0)
      Κ3=Ένα_Σημείο(0,0)
      Τμήμα Σχεδίασε {
                  Για .Κ1, Αυτό.Κ2, Αυτό.Κ3 {
                        Θέση .Χ,
                        Χάραξε Εως ..Χ,..Υ
                        Χάραξε Εως ...Χ,...Υ
                        Χάραξε Εως,
                  }
      }
Κλάση:
      Π
      Τμήμα Χ2 {
            Διάβασε
            Ένωσε .Π στη Π
            Για Κ {
                  *=Π
                  *=Π
            }
      }
       Τμήμα Τρίγωνο (.Κ1, .Κ2, .Κ3, ) {
             .Χ2 &.Κ1
             .Χ2 &.Κ2
             .Χ2 &.Κ3
       }
}
Τρ=Τρίγωνο(Κ, Λ, Μ, 15)
Τρ.Σχεδίασε


Τώρα βλέπουμε ότι υπάρχει μια Κλάση Τρίγωνο με την οποία φτιάχνουμε το Τρ και στο οποίο βάλαμε τα Κ, Λ και Μ με πέρασμα με τιμή και το 15 τον πολλαπλασιαστή. Στο Τρ δεν θα υπάρχει το Π, το τμήμα Χ2 και το τμήμα Τρίγωνο γιατί ορίσαμε να μην αντιγράφονται σε κλειστό αντικείμενο (με την ετικέτα Κλάση:)
Επιπλέον βλέπουμε ότι στο Τρ έχουμε τρεις άλλες ομάδες, τις οποίες αρχικά δώσαμε με μια τιμή (οι κλάσεις είναι γενικές συναρτήσεις εξ ορισμού, όταν ο ορισμός είναι εκτός ομάδας), την Ένα_Σημείο(0,0). Το νέο εδώ είναι ότι υπάρχει η Σχεδίασε, ένα τμήμα στη Τρ που σχεδιάζει το τρίγωνο από τα τρία σημεία. Ενώ σαν τμήμα το τρίγωνο έκανε δυο εργασίες πάντα, την επεξεργασία των σημείων βάσει του πολλαπλασιαστή, και την σχεδίαση, εδώ με την χρήση του αντικειμένου μπορούμε να κάνουμε την σχεδίαση όσες φορές θέλουμε, γιατί έχουμε στην ουσία τις δυο εργασίες ως μια εργασία κατά την δημιουργία και την δεύτερη σε κάθε ζήτηση. Βλέπουμε δηλαδή ότι η χρήση αντικειμένου, δίνει πρόσθετες; δυνατότητες για τον προγραμματιστή.



Αν δεν είχαμε τα αντικείμενα θα έπρεπε ή να κάνουμε υπολογισμούς κατά την εκτέλεση κάθε φορά της Τρίγωνο, ή να χρησιμοποιούσαμε γενικές μεταβλητές, όπου κάποια στιγμή θα έπρεπε για κάθε μια γενική να έχουμε ξεχωριστό κώδικα, ή να φτιάξουμε πίνακες γενικούς και πάλι να έχουμε κώδικα για κάθε περίπτωση, και το πρόγραμμα θα ήταν "μοναδικό" για την περίπτωση που γράφτηκε. Εδώ όμως με την χρήση των αντικειμένων, το κάθε μέρος κώδικα ασχολείται με μέλη αντικειμένων και οι τυχόν αναβαθμίσεις αυτών δεν θα επιφέρει αλλαγή στον κώδικα που ήδη "Τρέχει".



Αν πειράξουμε τα ονόματα των Χ και Υ τότε σπάμε την συμβατότητα με τον υπάρχον κώδικα. Οπότε όταν μιλάμε για αναβάθμιση πάντα λέμε για νέα ονόματα, νέα τμήματα, νέες μεταβλητές.



Με μια εντολή Τρ1=Τρ παίρνουμε αντίγραφο του Τρ στο Τρ1. Σε αυτά τα παραδείγματα δεν έχουμε ορίσει κάποια μέλη ιδιωτικά. Τα δε σημεία μπορούν να αλλαχθούν όποτε θέλουμε με συγχώνευση με νέα σημεία που φτιάχνουμε με την Ένα_Σημείο().



Αν αύριο θέλουμε στο σημείο της κορυφής του τριγώνου να βάζουμε ένα κύκλο, τότε θα πρέπει να αλλάξουμε τον κώδικα ή να έχουμε κάνει μια αλλαγή εξ αρχής, ώστε να μην χρειαστεί να κάνουμε αλλαγή στο κώδικα αλλά διαμόρφωση το κώδικα που χρησιμοποιούμε το αντικείμενο αυτό. Δείτε πως γίνεται αυτό:

Χρήση Γεγονότος Σε Ομάδα


Μέλος μιας ομάδας μπορεί να είναι ένα αντικείμενο Γεγονός. Το γεγονός περιέχει μια λίστα συναρτήσεων που καλεί με την Κάλεσε Γεγονός και έχει προκαθορισμένο αριθμό και τύπο ορισμάτων. Σε κάθε κλήση όλα τα ορίσματα θα πάνε ως έχουν σε όλες τις συναρτήσεις. Στο πρόγραμμα παρακάτω έχει τροποποιηθεί η κλάση Τρόγωνο για να περιλαμβάνει ένα αντικείμενο Γεγονός και κώδικα στην Σχεδίασε που εκτελεί το σχεδιασμό μέσω κλήσεως γεγονότος.
Βάζουμε το κώδικα (Κλάση Ένα_Σημείο(....Μ=Ενα_σημείο(200, 500) που έχει ήδη δοθεί)



 Κλάση Τρίγωνο {
      Γεγονός Μ {
            Διάβασε Χ, Υ, Χ1, Υ1
      }
      Κ1=Ένα_Σημείο(0,0)
      Κ2=Ένα_Σημείο(0,0)
      Κ3=Ένα_Σημείο(0,0)
      Τμήμα Σχεδίασε {
            Διάβασε &ΜΜ()
            Γεγονός .Μ Νέο ΜΜ()
            Για .Κ1, Αυτό.Κ2, Αυτό.Κ3 {
                  Κάλεσε Γεγονός Αυτό.Μ,,, ..Χ, ..Υ
                  Κάλεσε Γεγονός Αυτό.Μ, ..Χ,..Υ, ...Χ, ...Υ
                  Κάλεσε Γεγονός Αυτό.Μ, ...Χ,...Υ,,
            }
            Γεγονός .Μ Πέτα ΜΜ()
      }
Κλάση:
      Π
      Τμήμα Χ2 {
            Διάβασε
            Ένωσε .Π στη Π
            Για Κ {
                  *=Π
                  *=Π
            }
      }
       Τμήμα Τρίγωνο (.Κ1, .Κ2, .Κ3, ) {
             .Χ2 &.Κ1
             .Χ2 &.Κ2
             .Χ2 &.Κ3
       }
}
Συνάρτηση Γραμμή1 {
      Διάβασε Χ1, Υ1, Χ2, Υ2
      Θέση Χ1, Υ1
      Πάχος 3 {
            Χάραξε Εως Χ2, Υ2
      }
}
Συνάρτηση Κύκλ1 {
      Διάβασε Χ1, Υ1
      Θέση Χ1, Υ1
     Πάχος 3 { Κύκλος 300}
}
Τρ=Τρίγωνο(Κ, Λ, Μ, 15)
Γεγονός Τρ.Μ Νέο Κύκλ1()
Τρ.Σχεδίασε &Γραμμη1()



Δείτε λοιπόν ότι αρχικά βάζουμε στο Τρ.Μ μια συνάρτηση Κυκλ1() η οποία διαβάζει μόνο τα δυο πρώτα στοιχεία στο σωρό τιμών και με αυτά μεταθέτει τον δρομέα γραφικών και φτιάχνει έναν κύκλο.



Κατόπιν καλούμε την Σχεδίασε δίνοντας με αναφορά μια συνάρτηση. Αυτή η συνάρτηση δέχεται δυο σημεία και χαράζει μια γραμμή με πάχος 3 εικονοστοιχεία. Αυτό που ξεκάθαρα βλέπουμε είναι ότι το τμήμα Σχεδίασε της Τρ δέχεται μια παράμετρο, μια συνάρτηση την οποία βάζει στο γεγονός και την βγάζει όταν τερματίσει την χρήση του. Θα μπορούσαμε να αλλαξουμε τον σχεδιασμό, να μην δέχεται η Σχεδίασε το &Γραμμή1() και να βάζαμε στην προηγούμενη εντολή μετά την Κυκλ1() το κόμμα και το Γραμμή1().

Βάζουμε το κώδικα (Κλάση Ένα_Σημείο(....Μ=Ενα_σημείο(200, 500) που έχει ήδη δοθεί)

 Κλάση Τρίγωνο {
      Γεγονός Μ {
            Διάβασε Χ, Υ, Χ1, Υ1
      }
      Κ1=Ένα_Σημείο(0,0)
      Κ2=Ένα_Σημείο(0,0)
      Κ3=Ένα_Σημείο(0,0)
      Τμήμα Σχεδίασε {
            Για .Κ1, Αυτό.Κ2, Αυτό.Κ3 {
                  Κάλεσε Γεγονός Αυτό.Μ,,, ..Χ, ..Υ
                  Κάλεσε Γεγονός Αυτό.Μ, ..Χ,..Υ, ...Χ, ...Υ 
                  Κάλεσε Γεγονός Αυτό.Μ, ...Χ,...Υ,,
            }
      }
Κλάση:
      Π
      Τμήμα Χ2 {
            Διάβασε
            Ένωσε .Π στη Π
            Για Κ {
                  *=Π
                  *=Π
            }
      }
       Τμήμα Τρίγωνο (.Κ1, .Κ2, .Κ3, ) {
             .Χ2 &.Κ1
             .Χ2 &.Κ2
             .Χ2 &.Κ3
       }
}
Συνάρτηση Γραμμή1 {
      Διάβασε Χ1, Υ1, Χ2, Υ2
      Θέση Χ1, Υ1
      Πάχος 3 {
            Χάραξε Εως Χ2, Υ2
      }
}
Συνάρτηση Κύκλ1 {
      Διάβασε Χ1, Υ1
      Θέση Χ1, Υ1
     Πάχος 3 { Κύκλος 300}
}
Τρ=Τρίγωνο(Κ, Λ, Μ, 15)
Γεγονός Τρ.Μ Νέο Κύκλ1(), Γραμμή1()
Τρ.Σχεδίασε


Βλέπουμε ότι η Τρ (που φτιάχτηκε από την Κλάση Τρίγωνο) δεν έχει τις εντολές γραφικών, παρά μόνο καλεί ένα γεγονός το οποίο μεταφέρει συγκεκριμένα στοιχεία. Οι κλήσεις σε γεγονότα γίνονται και με τιμές με αναφορά, αν έχει δηλωθεί αυτό. Όπως βλέπουμε το γεγονός Μ έχει δηλωθεί με τέσσερις παραμέτρους, με πέρασμα με τιμή.

Αν δεν βάλουμε την Γεγονός Τρ.Μ Νέο ..... δηλαδή αν το γεγονός δεν πάρει συνάρτηση θα εκτελεστεί η Τρ.Σχεδίασε χωρίς να βγει λάθος. Οι κλήσεις στα γεγονότα γίνονται ακόμα και όταν δεν υπάρχει κάτι να τα εξυπηρετήσει. Απλά ο διερμηνευτής όταν δεν βρίσκει συνάρτηση, επιστρέφει άμεσα, σαν να είχε καλέσει μια!

Τα γεγονότα ακόμα και αν έχουν συναρτήσεις δέχονται εντολή Κράτησε για να μην τις χρησιμοποιήσουν, ως διακόπτης δηλαδή. Δείτε την βοήθεια στην Γεγονός (και τα Καθαρό, Κράτησε, Άφησε, Πέτα, Νέο που μπορούν να υπάρχουν μετά το όνομα του γεγονότος)



Χρήση Ελαφριών Γεγονότων



Εδώ τα ελαφριά γεγονότα δεν έχουν αντικείμενο, δεν έχουν δηλαδή δυνατότητες να προσθέσουμε ή να αφαιρέσουμε, ή να σταματήσουμε όπως με το αντικείμενο.  Επιπλέον δεν υπάρχει υπογραφή παραμέτρων, γιατί δεν υπάρχει πολλαπλή εκτέλεση συναρτήσεων εξυπηρέτησης. Εδώ έχουμε βάλει δυο γεγονότα, και καλούμε πρώτα το γεγονός "Γραμμή" για τις πλευρές του τριγώνου και μετά το γεγονός Κύκλος για κυκλάκια στις γωνίες του τριγώνου.

Βάζουμε το κώδικα (Κλάση Ένα_Σημείο(....Μ=Ενα_σημείο(200, 500) που έχει ήδη δοθεί)

Κλάση Τρίγωνο {
      Γεγονότα "Γραμμή", "Κύκλος"
      Κ1=Ένα_Σημείο(0,0)
      Κ2=Ένα_Σημείο(0,0)
      Κ3=Ένα_Σημείο(0,0)
      Τμήμα Σχεδίασε {
            Για .Κ1, Αυτό.Κ2, Αυτό.Κ3 {
                  Κάλεσε Γεγονός "Γραμμή", ,, ..Χ, ..Υ
                  Κάλεσε Γεγονός "Γραμμή", ..Χ,..Υ, ...Χ, ...Υ
                  Κάλεσε Γεγονός "Γραμμή", ...Χ,...Υ, ,
                  Κάλεσε Γεγονός "Κύκλος", ,
                  Κάλεσε Γεγονός "Κύκλος", ..Χ,..Υ
                  Κάλεσε Γεγονός "Κύκλος", ...Χ,...Υ
            }
      }
Κλάση:
      Π
      Τμήμα Χ2 {
            Διάβασε
            Ένωσε στη Π
            Για Κ {
                  *=Π
                  *=Π
            }
      }
       Τμήμα Τρίγωνο (.Κ1, .Κ2, .Κ3, ) {
             .Χ2 &.Κ1
             .Χ2 &.Κ2
             .Χ2 &.Κ3
       }
}
Ομάδα ΜεΓεγονότα Τρ=Τρίγωνο(Κ, Λ, Μ, 15)
Συνάρτηση Τρ_Γραμμή {
      Διάβασε Νέο Χ1, Υ1, Χ2, Υ2
      Θέση Χ1, Υ1
      Πάχος 3 {
            Χάραξε Εως Χ2, Υ2
      }
}
Συνάρτηση Τρ_Κύκλος {
      Διάβασε Νέο Χ1, Υ1
      Θέση Χ1, Υ1
     Πάχος 3 { Κύκλος 300}
}

Τρ.Σχεδίασε




Περί δεικτών σε ομάδες θα δούμε εδώ


Από την αναθεώρηση 38 (έκδοση 8.9) προστέθηκε η Υπερκλάση, δηλαδή μια κλάση που κληρονομεί όχι μόνο τα μέλη της αλλά δίνει και μια εσωτερική σύνδεση με στοιχεία που έχει η κλάση μοναδικά (τιμές δηλαδή που έχει η Υπερκλάση μόνο), ή μπορεί να έχει παράλληλα και έτσι κάθε  αντικείμενο που σχετίζεται με την υπερκλάση μπορεί να έχει μέλη της Υπερκλάσης (τιμές δηλαδή) που βλέπει κάθε άλλο αντικείμενο που σχετίζεται με την ίδια υπερκλάση. Η συγχώνευση ενός αντικειμένου που έχει σύνδεση με υπερκλάση βγάζει ένα νέο αντικείμενο με την ίδια υπερκλάση. Μπορουν ομάδες μέσα σε ομάδες να έχουν δική τους υπερκλάση, έτσι ένα αντικείμενο μπορεί να έχει πάνω από δυο υπερκλάσεις αλλά μόνο μια ανά επίπεδο ομάδας. (Τα αντικείμενα της Μ2000, ομάδες είναι πολυεπίπεδα αν έχουμε εσωτερικές ομάδες)

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.