Περίγραμμα! Προσδιοριστές πρόσβασης και απόκρυψη πληροφορίας! Προγραμματιστικές Συμβάσεις ΠΡΟΣΔΙΟΡΙΣΤΕΣ ΠΡΟΣΒΑΣΗΣ Access Specifiers 1 2 Προσδιοριστές Πρόσβασης! Βασική αρχή:! Μια κλάση ελέγχει την πρόσβαση που μπορούν να αποκτήσουν άλλες κλάσεις στα μέλη της.! Οι προσδιοριστές πρόσβασης public, protected και private της Java χρησιμοποιούνται μπροστά από τον ορισμό κάθε µέλους μιας κλάσης (είτε μεθόδου είτε δεδομένου) και καθορίζουν τις δυνατές προσβάσεις προς αυτό. Πρόσβαση βιβλιοθήκης! Σε περίπτωση που δεν χρησιμοποιείται προσδιοριστής πρόσβασης, έχουμε τον προκαθορισμένο (default) προσδιοριστής πρόσβασης, ο οποίος αναφέρεται σαν «φιλικός» (friendly):! Ο φιλικός προσδιοριστής υποδηλώνει ότι όλες οι κλάσεις σε ένα πακέτο (βιβλιοθήκη) έχουν πρόσβαση στα «φιλικά» μέλη, τα οποία όμως εμφανίζονται ως «ιδιωτικά» σε όλες τις κλάσεις έξω από την βιβλιοθήκη.! Αφού μια μονάδα μετάφρασης (αρχείο) μπορεί να ανήκει σε μια μόνο βιβλιοθήκη, όλες οι κλάσεις μέσα σε αυτή θεωρούνται αυτομάτως φιλικές η μια προς την άλλη. 3 4
Παροχή Πρόσβασης " Για να δοθεί πρόσβαση προς τα μέλη μιας κλάσης, από άλλες κλάσεις, υπάρχουν οι εξής εναλλακτικές δυνατότητες:! Να καταστεί το μέλος της κλάσης που μας ενδιαφέρει δηµόσιο. Όλοι μπορούν να έχουν πρόσβαση σε αυτό.! Να γίνει το μέλος της κλάσης που μας ενδιαφέρει φιλικό, οριζόμενο χωρίς κανέναν προσδιοριστή και οι υπόλοιπες κλάσεις να τοποθετηθούν στην ίδια βιβλιοθήκη.! Στην περίπτωση κληρονομικότητας, με χρήση του προσδιοριστή protected.! Με δήλωση μεθόδων πρόσβασης/τροποποίησης (accessor/ mutator - αναγνώστες/τροποποιητές), οι οποίες διαβάζουν και γράφουν κάποιες τιμές-μέλη της κλάσης που μας αφορά. Η χρήση του public package c05.dessert; public class Cookie { public Cookie() { System.out.println("Cookie constructor"); void bite() { System.out.println("bite"); import c05.dessert.*; public class Dinner { public Dinner() { System.out.println("Dinner constructor"); public static void main(string[] args) { Cookie x = new Cookie(); //! x.bite(); // Can't access 5 6 To προκαθορισμένο (default) πακέτο public class Cake { public static void main(string[] args) { Pie x = new Pie(); x.f(); Cake.java file public class Pie { Pie.java file void f() { System.out.println("Pie.f()"); " Η κλάση Cake μπορεί να χρησιμοποιήσει τη μέθοδο f() της Pie, εφόσον η Cake και η Pie βρίσκονται στον ίδιο κατάλογο, δεν ανήκουν ρητά σε κάποια βιβλιοθήκη και άρα ο μεταφραστής θεωρεί ότι ανήκουν στο προκαθορισμένο «πακέτο». Ιδιωτικά μέλη " Ο προσδιοριστής πρόσβασης private υποδηλοί ότι κανείς δεν έχει πρόσβαση στο «ιδιωτικό» μέλος μιας κλάσης, εκτός από τις μεθόδους που είναι εσωτερικές σε αυτή την κλάση. " Άλλες κλάσεις της ίδιας βιβλιοθήκης επίσης δεν έχουν πρόσβαση σε ιδιωτικά μέλη της κλάσης. Π.χ.: class Sundae { private Sundae() { static Sundae makeasundae() { return new Sundae(); public class IceCream { public static void main(string[] args) { Sundae y = new Sundae(); Sundae x = Sundae.makeASundae(); 7 8
Διαπροσωπεία και Υλοποίηση " Ο έλεγχος πρόσβασης αποτελεί τον μηχανισμό της JAVA για επίτευξη της απόκρυψης πληροφορίας (information hiding) ή απόκρυψης της υλοποίησης. " Η ενσωμάτωση δεδομένων και μεθόδων σε συνδυασμό με την απόκρυψη υλοποίησης αποκαλείται ενθυλάκωση (encapsulation) και μας επιτρέπει να ορίζουμε νέους τύπους δεδομένων με χαρακτηριστικά και συμπεριφορές. " Ο έλεγχος πρόσβασης περιορίζει την πρόσβαση σε έναν τύπο δεδομένων, για δύο λόγους:! Για να προσδιορίσει τι μπορούν και τι δεν μπορούν να χρησιμοποιήσουν «τρίτοι» προγραμματιστές (client programmers): ο προγραμματιστής μιας κλάσης μπορεί να υλοποιήσει εσωτερικούς μηχανισμούς χωρίς να φοβάται ότι κάποιος τρίτος προγραμματιστής θα τους χρησιμοποιήσει κατά τρόπο μη ενδεδειγμένο.! Για να διαχωρίσει τη διαπροσωπεία από την υλοποίηση. Εφόσον η πρόσβαση τρίτων προγραμματιστών περιορίζεται στα δημόσια μέλη της κλάσης (τη διαπροσωπεία της), ο προγραμματιστής της κλάσης μπορεί να αλλάξει ελεύθερα ο,τιδήποτε δεν είναι δημόσιο χωρίς να επηρεάζει τον κώδικα των τρίτων προγραμματιστών. Πρόσβαση κλάσης (class access)! Οι προσδιοριστές πρόσβασης μπορούν να χρησιμοποιηθούν και για τον καθορισμό των κλάσεων μιας βιβλιοθήκης που είναι προσβάσιμες είτε μέσα από την ίδια βιβλιοθήκη είτε από άλλες βιβλιοθήκες.! Μια κλάση μπορεί να προσδιορισθεί µόνο σαν φιλική ή σαν δημόσια.! Κανονικές (μη εσωτερικές) κλάσεις δεν μπορούν να συνδυαστούν με προσδιοριστές πρόσβασης private ή protected. 9 10 Περιορισμοί στο Class Access! Το πολύ μια public κλάση σε μια μονάδα μετάφρασης (αρχείο Java).! Το όνομα της public κλάσης πρέπει να είναι το ίδιο με το όνομα του αρχείου που την περιλαμβάνει.! Είναι αποδεκτό (αλλά όχι συνηθισμένο) να έχουμε μια μονάδα μετάφρασης χωρίς δημόσια κλάση στο εσωτερικό της.! Στην περίπτωση αυτή, το όνομα του αρχείου μπορεί να είναι οποιοδήποτε (καλό είναι, όμως, να μην χρησιμοποιούμαι άσχετα ονόματα). Καλές προγραμματιστικές πρακτικές! Όταν κατασκευάζετε μια κλάση είναι σκόπιμο να δηλώσετε τα πεδία δεδομένων της σαν ιδιωτικά, για να τα προστατεύσετε από ανεπιθύμητες αλλαγές από άλλες κλάσεις.! Αυτό ισχύει ακόμα κι αν η κλάση σας είναι προσβάσιμη από τη βιβλιοθήκη της μόνο (όχι δημόσια).! Επίσης, είναι συνήθως λογικό να δώσετε στις μεθόδους της κλάσης την ίδια προσβασιμότητα με την κλάση, δηλαδή είτε δημόσια είτε φιλική.! Αν θέλετε να αποκλείσετε τη χρήση μιας κλάσης από οποιονδήποτε τρίτο προγραμματιστή, μπορείτε να καταστήσετε όλους τους κατασκευαστές της private. Έτσι, κανείς δεν μπορεί να δημιουργήσει αντικείμενα της κλάσης, εκτός από εσάς (μέσω από ένα στατικό μέλος της κλάσης). 11 12
Παράδειγμα class Soup1 { private Soup1() { public static Soup1 makesoup() { return new Soup(); class Soup2 {// singleton private Soup2() { private static Soup2 ps1 = new Soup2(); public static Soup2 access() { return ps1; public void f() { Παράδειγμα (συνέχεια) public class Lunch { void test1() { // Soup priv1 = new Soup(); void test2() { Soup1 soup = Soup1.makeSoup(); Soup2.access().f(); 13 14 Προγραμματιστικές Συμβάσεις JAVA 15 Προγραμματιστικές συμβάσεις [Coding conventions]! Σύνολο από κατευθυντήριες γραμμές σχετικά με το προγραμματιστικό στυλ, καλές πρακτικές και μεθόδους προγραμματισμού που πρέπει να ακολουθούνται κατά τον προγραμματισμό σε μια συγκεκριμένη γλώσσα.! Αφορούν συνήθως την οργάνωση αρχείων, στοίχιση εντολών, σχολιασμό, δηλώσεις, εντολές, κενό χώρο, συμβάσεις ονοματολογίας, προγραμματιστικές πρακτικές, πρακτικούς κανόνες προγραμματισμού, καλές πρακτικές αρχιτεκτονικής λογισμικού κλπ.! Η τήρηση των συμβάσεων αυτών βελτιώνει την δομική ποιότητα του λογισμικού, διευκολύνει την αναγνωσιμότητα πηγαίου κώδικα και την συντήρηση κώδικα.! Προγραμματιστικές συμβάσεις για τη JAVA καθορίστηκαν αρχικά από τη Sun στο έγγραφο Code Conventions for the Java TM Programming Language του 1999.! Νεώτερες συμβάσεις για τον προγραμματισμό σε JAVA θα βρείτε από τη Google στο Google Java Style και από το Software Engineering Institute του Carnegie Mellon University στο έγγραφο Java Coding Guidelines, όπου δίνεται έμφαση και σε θέματα ασφάλειας κώδικα. 16
Λόγοι Υιοθέτησης Συμβάσεων! Οι προγραμματιστικές συμβάσεις είναι σημαντικές για μια σειρά λόγων:! 80% του χρόνου κωδικοποίησης ενός προγράμματος αφορά στην συντήρησή του.! Σπάνια κάποιο λογισμικό συντηρείται από τον αρχικό προγραμματιστή.! Προγραμματιστικές συμβάσεις βελτιώνουν την αναγνωσιμότητα του λογισμικού και διευκολύνουν τους προγραμματιστές να κατανοούν τα προγράμματα πιό γρήγορα και καλύτερα.! Αν ο πηγαίος κώδικά σας πρόκειται να κυκλοφορήσει σαν προϊόν,θα πρέπει να είναι οργανωμένος και γραμμένος καθαρά. Οργάνωση Αρχείων JAVA! Ένα αρχείο αποτελείται από τμήματα, τα οποία πρέπει να διαχωρίζονται με κενές γραμμές και προαιρετικά σχόλια περιγραφής του κάθε σχήματος.! Αρχεία μεγαλύτερα από 2000 γραμμές είναι δυσανάγνωστα και πρέπει να αποφεύγονται.! Κάθε αρχείο Java περιέχει μια μόνο δημόσια κλάση ή διαπροσωπεία. Όταν υπάρχουν ιδιωτικές κλάσεις ή διαπροσωπείες που σχετίζονται με την δημόσια κλάση, αυτές μπορούν να συμπεριληφθούν στο αρχείο της δημόσιας κλάσης, αλλά μετά τον ορισμό της.! Τα αρχεία της Java έχουν την ακόλουθη δομή:! Στην αρχή υπάρχουν σχόλια.! Ακολουθούν εντολές πακέτων (package)και εισαγωγών (import).! Δηλώσεις κλάσεων και διαπροσωπειών. 18 17 @ FFB A9 9EF CB B CEA CB 9 CDLE ; BC 9 Εντολές Πακέτων και Εντολών Εισαγωγής! Η πρώτη εντολή στα περισσότερα αρχεία Java αφορά στον ορισμό της βιβλιοθήκης (D ;9 στην οποία ανήκουν οι κλάσεις του αρχείου.! Ακολουθούν εντολές ενσωμάτωσης υπαρχουσών βιβλιοθηκών. Π.χ.: D ;9 ADCE D99E B F199E 19 20
Δηλώσεις Κλάσεων και Διαπροσωπειών Σύμφωνα με τις συμβάσεις της Java, η δήλωση μιας κλάσης περιλαμβάνει: 1. Σχόλιο για την τεκμηρίωση (documentation) της κλάσης ή διαπροσωπείας 2. Δήλωση κλάσης ή διαπροσωπείας. 3. Αν χρειάζεται, σχόλιο σχετικά με την υλοποίηση της κλάσης ή της διαπροσωπείας. 4. Ορισμούς μεταβλητών κλάσης (στατικών), με πρώτες τις public, ακολουθούμενες από τις protected, τις μη καθοριζόμενης πρόσβασης και τις private. 5. Ορισμούς μεταβλητών στιγμιοτύπου (instance variables), με την ίδια σειρά όπως και οι στατικές. 6. Κατασκευαστές (constructors) 7. Μέθοδοι D ;9 @ ADCE @ @ 8L *@ *@ @ FF 89F E D CB ;C9F 9E9 9EF CB E CE. EF B A9 / F B A9 D @ @ FF *@ 9 9B8F 2CA9 @ FF M ) @ FF AD@9A9B CB CAA9B B ;C 9E9 21 22 classvar1 documentation comment public static int classvar1; * classvar2 documentation comment that happens to be * more than one line long private static Object classvar2; instancevar1 documentation comment public Object instancevar1; instancevar2 documentation comment protected int instancevar2; instancevar3 documentation comment private Object[] instancevar3; *...constructor Blah documentation comment... public Blah() { //...implementation goes here... *...method dosomething documentation comment... public void dosomething() { //...implementation goes here... *...method dosomethingelse documentation comment... * @param someparam description public void dosomethingelse(object someparam) { //...implementation goes here... 23 24
Συμβάσεις Σχολίων: Γενικές Αρχές! Δύο ειδών σχόλια:! Υλοποίησης, που περιλαμβάνονται ανάμεσα σε /*..., ή έπονται του //! Αποδελτίωσης (documentation ή "doc comments"), που περιλαμβάνονται ανάμεσα σε... Τα σχόλια αποδελτίωσης, μπορούν να εξαχθούν αυτόματα σε εγχειρίδια HTML μορφότυπου, με χρήση του εργαλείου javadoc.! Τα σχόλια υλοποίησης χρησιμεύουν για τον αποκλεισμό κώδικα σε σχόλιο, ή τον σχολιασμό υλοποίησης.! Τα σχόλια τεκμηρίωσης-αποδελτίωσης στοχεύουν στην καταγραφή των προδιαγραφών του κώδικα (code specification), ανεξάρτητα της υλοποίησης.! Γενικά, τα σχόλια αποσκοπούν στην παράθεση επεξηγήσεων σχετικά με τον κώδικα για πράγματα που δεν είναι φανερά από τον κώδικα τον ίδιο.! Πάρα πολλά επεξηγηματικά σχόλια υποδηλώνουν συνήθως κακή σχεδίαση του κώδικα. Σχόλια Τεκμηρίωσης (doc comments)! Χρησιμεύουν στην αυτόματη αποδελτίωση σε εγχειρίδιο HTML από το εργαλείο javadoc.! Περιλαμβάνονται μεταξύ χαρακτήρων, με ένα σχόλιο για κάθε κλάση, διαπροσωπεία ή μέθοδο-μέλος κλάσης και πρέπει να εμφανίζονται ακριβώς πριν την δήλωση για την αποδελτίωση της οποίας εισάγονται: 9 AD@9 @ FF DEC 89F D @ @ FF AD@9 M! Ακολουθούν την στοίχιση της δήλωσης της οποίας προηγούνται.! Σχόλια αποδελτίωσης δεν πρέπει να τοποθετούνται μέσα στο σώμα μιας μεθόδου. 25 26 Σχόλια Τεκμηρίωσης (συνέχεια) Συμβάσεις Ονοματολογίας! Μπορούν να περιλαμβάνουν σημαντήρες (tags) @see, οι οποίοι επιτρέπουν την παραπομπή σε άλλα τμήματα των εγχειριδίων HTML, τα οποία δημιουργούνται από το javadoc.! Άλλοι χρησιμοποιούμενοι σημαντήρες είναι οι ακόλουθοι: @version @author author-information @since @param parameter-name description @return description @throws " Κλάσεις: Class names should be nouns, in mixed case with the first letter of each internal word capitalized. Try to keep simple and descriptive. Use whole words-avoid acronyms and abbreviations. " Διαπροσωπείες: Interface names should be capitalized like class names. " Μέθοδοι: Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized. " Μεταβλητές:! Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter. Internal words start with capital letters. Variable names should not start with underscore _ or dollar sign $ characters, even though both are allowed.! Variable names should be short yet meaningful. The choice of a variable name should be mnemonic- that is, designed to indicate to the casual observer the intent of its use. One-character variable names should be avoided except for temporary "throwaway" variables. Common names for temporary variables are,,, A, and B for integers;, 8, and 9 for characters. " Σταθερές: The names of variables declared class constants and of ANSI constants should be all uppercase with words separated by underscores ("_"). (ANSI constants should be avoided, for ease of debugging.) 27 28