Στη γλώσσα C#, οι τροποποιητές πρόσβασης αναφέρονται στις λέξεις-κλειδιά που χρησιμοποιούνται για να καθορίσουν το επίπεδο πρόσβασης σε μέλη μιας κλάσης. Οι τροποποιητές πρόσβασης παρέχουν έναν τρόπο να διαχωρίσουμε τα μέλη που είναι προσβάσιμα από άλλα μέλη και κώδικα εκτός της κλάσης.
Οι τροποποιητές πρόσβασης που χρησιμοποιούνται στην C# είναι οι εξής:
public
: Το μέλος είναι προσβάσιμο από οποιονδήποτε κώδικα, ανεξάρτητα από την τοποθεσία του.private
: Το μέλος είναι προσβάσιμο μόνο από την ίδια την κλάση στην οποία ανήκει. Άλλες κλάσεις δεν μπορούν να έχουν πρόσβαση σε ιδιωτικά μέλη.protected
: Το μέλος είναι προσβάσιμο από την ίδια την κλάση και από κληρονομούμενες κλάσεις. Δεν είναι προσβάσιμο από κώδικα εκτός της κλάσης ή των κληρονομούμενων κλάσεων.internal
: Το μέλος είναι προσβάσιμο μόνο από την ίδια την εντολή συλλογής (assembly). Δεν είναι προσβάσιμο από κώδικα που βρίσκεται σε διαφορετική εντολή συλλογής.protected internal
: Συνδυάζει την πρόσβασηprotected
καιinternal
. Το μέλος είναι προσβάσιμο από την ίδια την εντολή συλλογής και από κληρονομούμενες κλάσεις, ανεξάρτητα από την τοποθεσία τους.
Η χρήση τροποποιητών πρόσβασης στη γλώσσα C# μας επιτρέπει να ελέγχουμε την πρόσβαση σε μέλη κλάσεων και να προσφέρουμε την κατάλληλη επίπεδη προστασίας και ασφάλειας στον κώδικα μας.
using System; class Person { public string name; // Πεδίο με δημόσια πρόσβαση private int age; // Πεδίο με ιδιωτική πρόσβαση public void SayHello() { Console.WriteLine("Γεια σου! Το όνομά μου είναι " + name); } private void CelebrateBirthday() { age++; Console.WriteLine("Χρόνια πολλά! Είμαι τώρα " + age + " ετών."); } } class Program { static void Main() { Person person = new Person(); person.name = "Γιάννης"; person.SayHello(); // Προσπέλαση του πεδίου name (δημόσια πρόσβαση) Console.WriteLine("Το όνομά του είναι " + person.name); // Προσπέλαση της μεθόδου CelebrateBirthday (ιδιωτική πρόσβαση) // person.CelebrateBirthday(); // Σχολιασμένη γραμμή κώδικα: Απαγορεύεται η πρόσβαση στην ιδιωτική μέθοδο } }
Ο κώδικας δημιουργεί μια κλάση με όνομα “Person” που περιέχει δύο μέλη (πεδία) και δύο μεθόδους. Το πεδίο “name” είναι δημόσιο (public), προσβάσιμο από οποιονδήποτε έχει πρόσβαση στο αντικείμενο της κλάσης. Το πεδίο “age” είναι ιδιωτικό (private), άρα μπορεί να προσπελαστεί και να τροποποιηθεί μόνον από τις μεθόδους της ίδιας κλάσης.
Οι δύο μέθοδοι που περιέχονται στην κλάση “Person” είναι:
- Η δημόσια (public) μέθοδος “SayHello”: Εμφανίζει ένα μήνυμα που περιλαμβάνει το όνομα του αντικειμένου (της κλάσης “Person”) που καλεί την μέθοδο. Η μέθοδος δεν επιστρέφει τίποτα (τύπος επιστροφής “void”).
- Η ιδιωτική (private) μέθοδος “CelebrateBirthday”: Αυξάνει την ηλικία του αντικειμένου (της κλάσης “Person”) κατά 1 και εμφανίζει ένα μήνυμα που δηλώνει τη νέα ηλικία. Η μέθοδος επίσης δεν επιστρέφει τίποτα.
Στη συνέχεια, στην κλάση “Program” (η κύρια κλάση του προγράμματος), δημιουργείται ένα αντικείμενο “person” της κλάσης “Person”. Το πεδίο “name” του αντικειμένου ορίζεται ως “Γιάννης”
μετά από τον τελεστή εκχώρησης (=). Έπειτα, καλείται η μέθοδος “SayHello” του αντικειμένου “person”, που εμφανίζει ένα μήνυμα καλωσορίσματος με το όνομα “Γιάννης”.
Στη συνέχεια, υπάρχουν δύο σχόλια σχετικά με την προσπέλαση των μελών της κλάσης “Person”. Πρώτον, εμφανίζεται το πεδίο “name” του αντικειμένου “person” (πρόσβαση με δημόσια πρόσβαση). Δεύτερον, προσπαθείται να κληθεί η μέθοδος “CelebrateBirthday” του αντικειμένου “person” (πρόσβαση με ιδιωτική πρόσβαση). Ωστόσο, αυτή η γραμμή κώδικα έχει σχολιαστεί με δύο κάθετους πλευρικούς (//), οπότε αγνοείται κατά τη μεταγλώττιση και δεν εκτελείται.
Το αποτέλεσμα εκτέλεσης του προγράμματος θα είναι το εξής:
Γεια σου! Το όνομά μου είναι Γιάννης Το όνομά του είναι Γιάννης
Ο κώδικας εκτελεί τις εντολές με τη σειρά. Αρχικά, δημιουργείται ένα αντικείμενο “person” της κλάσης “Person”. Το πεδίο “name” του αντικειμένου ορίζεται ως “Γιάννης”. Στη συνέχεια, καλείται η μέθοδος “SayHello” του αντικειμένου “person”, που εμφανίζει το μήνυμα “Γεια σου! Το όνομά μου είναι Γιάννης”.
Στη συνέχεια, εκτυπώνεται το πεδίο “name” του αντικειμένου “person”, δηλαδή το μήνυμα “Το όνομά του είναι Γιάννης”.
Ωστόσο, η γραμμή κώδικα που προσπαθεί να καλέσει την ιδιωτική μέθοδο “CelebrateBirthday” έχει σχολιαστεί και αγνοείται κατά τη μεταγλώττιση. Άρα, η μέθοδος δεν εκτελείται και το μήνυμα “Χρόνια πολλά! Είμαι τώρα X ετών” δεν εμφανίζεται.
Οι προσδιοριστές πρόσβασης (access modifiers) όπως ο public
και ο private
χρησιμοποιούνται για να καθορίσουν το επίπεδο πρόσβασης των μελών μιας κλάσης. Ορίζουν ποια μέλη είναι ορατά και προσπελάσιμα από άλλες κλάσεις και μέρη του κώδικα. Η χρήση των προσδιοριστών πρόσβασης βοηθάει στην επίτευξη καλύτερης οργάνωσης του κώδικα και στην προστασία των δεδομένων και της λειτουργικότητας των κλάσεων.
Η λέξη-κλειδί public
είναι ένας προσδιοριστής πρόσβασης (access modifier) που χρησιμοποιείται για να ορίσει το επίπεδο πρόσβασης/ορατότητας για κλάσεις, πεδία, μεθόδους και ιδιότητες.
[adinserter block=”2″]
Η γλώσσα C# περιλαμβάνει τους ακόλουθους προσδιοριστές πρόσβασης:
public
: Ο κώδικας είναι προσβάσιμος από όλες τις κλάσεις.private
: Ο κώδικας είναι προσβάσιμος μόνο μέσα στην ίδια κλάση.protected
: Ο κώδικας είναι προσβάσιμος εντός της ίδιας κλάσης ή σε μια κλάση που κληρονομεί από αυτήν την κλάση. Θα μάθετε περισσότερα για την κληρονομικότητα σε ένα αργότερο κεφάλαιο.internal
: Ο κώδικας είναι προσβάσιμος μόνο εντός της ίδιας συλλογής (assembly), αλλά όχι από άλλη συλλογή. Θα μάθετε περισσότερα για αυτό σε ένα αργότερο κεφάλαιο.
Υπάρχουν επίσης δύο συνδυασμοί: protected internal
και private protected
.
Για τώρα, ας επικεντρωθούμε στους προσδιοριστές public
και private
.
Είναι σημαντικό να κατανοήσετε ότι οι προσδιοριστές πρόσβασης ελέγχουν ποια μέρη του κώδικα είναι προσβάσιμα από άλλες κλάσεις ή τμήματα του προγράμματος. Η επιλογή του κατάλληλου προσδιοριστή πρόσβασης εξαρτάται από τις απαιτήσεις και την αρχιτεκτονική του προγράμματος σας.
Αν δηλώσετε ένα πεδίο με τον προσδιοριστή πρόσβασης private
, μπορεί να προσπελαστεί μόνο μέσα στην ίδια κλάση:
using System; class MyClass { private int myPrivateField; public void MyMethod() { // Μπορείτε να αποκτήσετε πρόσβαση στο πεδίο myPrivateField εδώ, εντός της ίδιας κλάσης. myPrivateField = 10; } } class AnotherClass { public void AnotherMethod() { MyClass myObject = new MyClass(); // Δεν μπορείτε να αποκτήσετε πρόσβαση στο πεδίο myPrivateField εδώ, επειδή είναι ιδιωτικό (private). // myObject.myPrivateField = 20; // Μη έγκυρο! } }
Στο παραπάνω παράδειγμα, η μεταβλητή myPrivateField
έχει δηλωθεί ως ιδιωτική (private) μέσα στην κλάση MyClass
. Αυτό σημαίνει ότι μπορεί να προσπελαστεί και να τροποποιηθεί μόνο μέσα στην ίδια κλάση, όπως φαίνεται στην μέθοδο MyMethod
. Ωστόσο, δεν μπορεί να προσπελαστεί από άλλες κλάσεις, όπως φαίνεται στην κλάση AnotherClass
.
Ο προσδιοριστής private
είναι χρήσιμος για να περιορίσετε την πρόσβαση σε εσωτερικά πεδία ή μεθόδους της κλάσης, προσφέροντας έτσι μεγαλύτερη ελευθερία και ασφάλεια κατά την ανάπτυξη του κώδικα.
Αν προσπαθήσετε να αποκτήσετε πρόσβαση σε ένα ιδιωτικό πεδίο εκτός της κλάσης, θα προκληθεί ένα σφάλμα (συντακτικό ή εκτέλεσης), ανάλογα με το σημείο που γίνεται η προσπάθεια πρόσβασης.
Συνήθως, αν προσπαθήσετε να αποκτήσετε πρόσβαση σε ένα ιδιωτικό πεδίο από έναν άλλο κώδικα, θα λάβετε ένα σφάλμα στη σύνταξη του κώδικα κατά τη μεταγλώττιση (compile-time error).
[adinserter block=”3″]
Εδώ είναι ένα παράδειγμα που δείχνει το σφάλμα που προκαλείται όταν προσπαθείτε να αποκτήσετε πρόσβαση σε ένα ιδιωτικό πεδίο έξω από την κλάση:
class MyClass { private int myPrivateField; } class AnotherClass { public void AnotherMethod() { MyClass myObject = new MyClass(); // Προσπάθεια πρόσβασης σε ένα ιδιωτικό πεδίο έξω από την κλάση. myObject.myPrivateField = 20; // Σφάλμα κατά τη μεταγλώττιση (compile-time error). } }
Στο παραπάνω παράδειγμα, κατά τη μεταγλώττιση του κώδικα, θα λάβετε ένα σφάλμα που υποδεικνύει ότι η προσπάθεια πρόσβασης στο ιδιωτικό πεδίο myPrivateField
είναι μη έγκυρη.
Τονίζεται ότι το σφάλμα θα προκληθεί κατά τη μεταγλώττιση και όχι κατά την εκτέλεση του προγράμματος.
Αν δηλώσετε ένα πεδίο με τον προσδιοριστή πρόσβασης public
, είναι προσβάσιμο από όλες τις κλάσεις:
class MyClass { public int myPublicField; } class AnotherClass { public void AnotherMethod() { MyClass myObject = new MyClass(); // Μπορείτε να αποκτήσετε πρόσβαση στο δημόσιο πεδίο myPublicField εδώ, από μια άλλη κλάση. myObject.myPublicField = 20; } }
Στο παραπάνω παράδειγμα, το πεδίο myPublicField
έχει δηλωθεί ως δημόσιο (public) μέσα στην κλάση MyClass
. Αυτό σημαίνει ότι είναι προσβάσιμο από οποιαδήποτε άλλη κλάση. Στη μέθοδο AnotherMethod
της κλάσης AnotherClass
, μπορούμε να αποκτήσουμε πρόσβαση στο πεδίο myPublicField
και να το τροποποιήσουμε.
Ο προσδιοριστής public
χρησιμοποιείται για να δηλώσει κοινόχρηστα (public) μέλη μιας κλάσης, τα οποία είναι προσβάσιμα από οποιαδήποτε άλλη κλάση στο πρόγραμμα. Αυτό μπορεί να είναι χρήσιμο για πεδία που πρέπει να είναι προσβάσιμα από διάφορες τμήματα του προγράμματος. Ωστόσο, πρέπει να προσέξετε τη σωστή χρήση και να μην αποκαλύπτετε πεδία που πρέπει να παραμένουν ιδιωτικά για λόγους ασφαλείας ή σωστής λειτουργίας του προγράμματος.
Σημείωση: Από προεπιλογή, όλα τα μέλη μιας κλάσης είναι ιδιωτικά (private) εάν δεν καθορίσετε έναν προσδιοριστή πρόσβασης:
class MyClass { int myPrivateField; public int myPublicField; void MyPrivateMethod() { // Εσωτερική λειτουργία } public void MyPublicMethod() { // Δημόσια λειτουργία } }
Στο παραπάνω παράδειγμα, το πεδίο myPrivateField
και η μέθοδος MyPrivateMethod
είναι ιδιωτικά (private) επειδή δεν καθορίσαμε κανέναν προσδιοριστή πρόσβασης για αυτά. Αντίθετα, το πεδίο myPublicField
και η μέθοδος MyPublicMethod
έχουν τον προσδιοριστή πρόσβασης public
και είναι προσβάσιμα από οποιαδήποτε άλλη κλάση.
Είναι σημαντικό να έχετε υπόψη ότι, αν δεν καθορίσετε έναν προσδιοριστή πρόσβασης για ένα μέλος μιας κλάσης, τότε αυτό το μέλος θα έχει προεπιλεγμένα τον προσδιοριστή πρόσβασης private
.