1. Τι είναι η Ενθυλάκωση;

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

Παράδειγμα Καθημερινής Ζωής:

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

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


Παράδειγμα Ενθυλάκωσης στην C#:

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

class BankAccount
{
// Ιδιωτική μεταβλητή, δεν είναι προσβάσιμη απευθείας από έξω
private decimal balance;

// Δημόσια μέθοδος για να καταθέσεις χρήματα
public void Deposit(decimal amount)
{
    if (amount > 0)
    {
        balance += amount;
        Console.WriteLine($"Καταθέσατε: {amount}. Υπόλοιπο: {balance}");
    }
}

// Δημόσια μέθοδος για να πάρεις το υπόλοιπο
public decimal GetBalance()
{
    return balance;
}

}

class Program
{
static void Main()
{
BankAccount account = new BankAccount();

    // Δεν μπορούμε να προσπελάσουμε άμεσα την ιδιωτική μεταβλητή balance
    // account.balance = 100;  // Αυτό προκαλεί σφάλμα

    // Μπορούμε όμως να χρησιμοποιήσουμε τη δημόσια μέθοδο Deposit
    account.Deposit(50);  // Καταθέτει 50 ευρώ

    // Μπορούμε να διαβάσουμε το υπόλοιπο μέσω της δημόσιας μεθόδου GetBalance
    Console.WriteLine($"Υπόλοιπο λογαριασμού: {account.GetBalance()}");
}

}

Αναλυτική Εξήγηση:

Η μεταβλητή balance είναι private: Αυτό σημαίνει ότι δεν μπορείς να την αλλάξεις απευθείας από έξω. Είναι προστατευμένη.

Δημόσιες μέθοδοι Deposit() και GetBalance(): Αυτές οι μέθοδοι είναι δημόσιες (public) και μπορούν να χρησιμοποιηθούν από οποιονδήποτε θέλει να καταθέσει χρήματα ή να δει το υπόλοιπο του λογαριασμού.

Προστασία δεδομένων: Η ενθυλάκωση εξασφαλίζει ότι τα δεδομένα είναι ασφαλή και δεν αλλάζουν με ακατάλληλο τρόπο.

Αποτέλεσμα:

makefile

Καταθέσατε: 50. Υπόλοιπο: 50
Υπόλοιπο λογαριασμού: 50

Γιατί είναι σημαντική η Ενθυλάκωση;

Προστασία Δεδομένων: Η ενθυλάκωση προστατεύει τα δεδομένα μιας κλάσης από εξωτερικές αλλαγές ή κακή χρήση.
Ασφάλεια: Η ενθυλάκωση επιτρέπει τη χρήση ελέγχων πριν αλλάξουμε δεδομένα (π.χ., στο παράδειγμα, η μέθοδος Deposit() ελέγχει αν το ποσό είναι θετικό).
Ευελιξία: Αν θέλεις να αλλάξεις τον τρόπο που λειτουργούν οι εσωτερικές λεπτομέρειες μιας κλάσης, δεν χρειάζεται να αλλάξεις τον τρόπο που χρησιμοποιείται η κλάση από εξωτερικό κώδικα.
  1. Τι είναι τα Αφηρημένα Δεδομένα (Abstraction);

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

Σκέψου πάλι το αυτοκίνητο. Για να το οδηγήσεις, δεν χρειάζεται να ξέρεις πώς λειτουργεί ο κινητήρας, τα συστήματα πέδησης ή η μετάδοση κίνησης. Το μόνο που χρειάζεται να ξέρεις είναι πώς να χρησιμοποιείς το τιμόνι, το γκάζι και τα φρένα. Όλα τα εσωτερικά στοιχεία του αυτοκινήτου είναι κρυμμένα από σένα, γιατί δεν τα χρειάζεσαι για να οδηγήσεις.

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

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

csharp

// Αφηρημένη κλάση Animal
abstract class Animal
{
public string Name { get; set; }

// Αφηρημένη μέθοδος που πρέπει να υλοποιηθεί από τις υποκλάσεις
public abstract void MakeSound();

}

// Υποκλάση Dog που υλοποιεί τη μέθοδο MakeSound
class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine($”{Name} γαβγίζει!”);
}
}

// Υποκλάση Cat που υλοποιεί τη μέθοδο MakeSound
class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine($”{Name} νιαουρίζει!”);
}
}

class Program
{
static void Main()
{
Animal myDog = new Dog { Name = “Rex” };
Animal myCat = new Cat { Name = “Milo” };

    // Δεν μας νοιάζει πώς ακριβώς μιλάει το ζώο, απλά καλούμε τη μέθοδο
    myDog.MakeSound();  // Rex γαβγίζει!
    myCat.MakeSound();  // Milo νιαουρίζει!
}

}

Αναλυτική Εξήγηση:

Αφηρημένη κλάση Animal: Αυτή η κλάση έχει μια αφηρημένη μέθοδο MakeSound(), που σημαίνει ότι δεν ξέρουμε πώς ακριβώς θα υλοποιηθεί η μέθοδος. Αυτό το αφήνουμε στις υποκλάσεις.

    υποκλάσεις.

Υποκλάσεις Dog και Cat: Οι υποκλάσεις υλοποιούν τη μέθοδο MakeSound() με δικό τους τρόπο. Ο σκύλος γαβγίζει και η γάτα νιαουρίζει.

Χρήση της Αφαίρεσης: Από την πλευρά του προγραμματιστή που χρησιμοποιεί την κλάση, δεν μας ενδιαφέρει πώς ακριβώς λειτουργεί η MakeSound() για κάθε ζώο. Μας ενδιαφέρει μόνο ότι το ζώο μπορεί να κάνει έναν ήχο όταν το καλέσουμε.

Αποτέλεσμα:

Rex γαβγίζει!
Milo νιαουρίζει!

Γιατί είναι σημαντικά τα Αφηρημένα Δεδομένα;

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

Συμπέρασμα για Ενθυλάκωση και Αφηρημένα Δεδομένα:

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

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

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

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

  1. Συνδυασμός Ενθυλάκωσης και Αφαίρεσης

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

Συνήθως:

Ενθυλάκωση: Κρύβουμε τις μεταβλητές ή μεθόδους που δεν πρέπει να τροποποιηθούν άμεσα.
Αφαίρεση: Κρύβουμε την περίπλοκη υλοποίηση και προβάλλουμε μόνο τα απαραίτητα κομμάτια μέσω διεπαφών και δημόσιων μεθόδων.
  1. Ιδιότητες (Properties) και Ενθυλάκωση

Στην C#, υπάρχει ένα εξαιρετικό εργαλείο που μας επιτρέπει να ελέγχουμε πώς προσπελάζονται οι ιδιωτικές μεταβλητές: οι ιδιότητες (properties). Οι ιδιότητες μας επιτρέπουν να ελέγχουμε την ανάγνωση και εγγραφή μιας μεταβλητής, χωρίς να επιτρέπουμε άμεση πρόσβαση σε αυτήν.
Παράδειγμα Χρήσης Ιδιοτήτων:

csharp

class Person
{
// Ιδιωτική μεταβλητή
private int age;

// Δημόσια ιδιότητα για να ελέγχεις την πρόσβαση στην ηλικία
public int Age
{
    get { return age; }
    set
    {
        if (value > 0 && value < 150)  // Έλεγχος εγκυρότητας
        {
            age = value;
        }
        else
        {
            Console.WriteLine("Μη έγκυρη ηλικία.");
        }
    }
}

}

class Program
{
static void Main()
{
Person person = new Person();

    // Χρήση της ιδιότητας Age
    person.Age = 30;  // Θέτει την ηλικία
    Console.WriteLine($"Η ηλικία είναι: {person.Age}");  // Διαβάζει την ηλικία

    person.Age = -5;  // Προσπαθεί να θέσει μη έγκυρη ηλικία
}

}

Αναλυτική Εξήγηση:

Ιδιωτική μεταβλητή age: Η ιδιωτική μεταβλητή δεν μπορεί να προσπελαστεί απευθείας από εξωτερικό κώδικα.
Ιδιότητα Age: Η δημόσια ιδιότητα επιτρέπει την ασφαλή πρόσβαση στη μεταβλητή age. Ο έλεγχος που γίνεται στο set μέρος διασφαλίζει ότι η ηλικία είναι έγκυρη πριν αποθηκευτεί.
Αυτό είναι ένα παράδειγμα ενθυλάκωσης που χρησιμοποιεί ιδιότητες για να προστατέψει τα δεδομένα και να ελέγξει την ορθή χρήση τους.

Αποτέλεσμα:

Η ηλικία είναι: 30
Μη έγκυρη ηλικία.

  1. Διεπαφές (Interfaces) και Αφαίρεση

Οι διεπαφές (interfaces) είναι ένα ισχυρό εργαλείο για να δημιουργήσεις αφαίρεση στον κώδικά σου. Μια διεπαφή ορίζει τι μπορεί να κάνει μια κλάση, χωρίς να αποκαλύπτει πώς το κάνει. Οι κλάσεις που υλοποιούν μια διεπαφή δεσμεύονται να υλοποιήσουν τις μεθόδους που δηλώνονται σε αυτήν.
Παράδειγμα Διεπαφών:

csharp

// Διεπαφή που ορίζει τι μπορεί να κάνει ένα ζώο
interface IAnimal
{
void MakeSound(); // Όλα τα ζώα πρέπει να έχουν μια μέθοδο MakeSound
}

// Κλάση Dog που υλοποιεί τη διεπαφή IAnimal
class Dog : IAnimal
{
public void MakeSound()
{
Console.WriteLine(“Ο σκύλος γαβγίζει!”);
}
}

// Κλάση Cat που υλοποιεί τη διεπαφή IAnimal
class Cat : IAnimal
{
public void MakeSound()
{
Console.WriteLine(“Η γάτα νιαουρίζει!”);
}
}

class Program
{
static void Main()
{
IAnimal myDog = new Dog();
IAnimal myCat = new Cat();

    myDog.MakeSound();  // Ο σκύλος γαβγίζει!
    myCat.MakeSound();  // Η γάτα νιαουρίζει!
}

}

Αναλυτική Εξήγηση:

Η διεπαφή IAnimal ορίζει τη μέθοδο MakeSound(), αλλά δεν περιέχει καμία πληροφορία για το πώς τα ζώα κάνουν ήχο.
Οι κλάσεις Dog και Cat υλοποιούν τη διεπαφή και παρέχουν τις δικές τους υλοποιήσεις για το πώς κάνουν ήχο.
Αυτό είναι ένα παράδειγμα αφαίρεσης όπου μπορούμε να δουλεύουμε με τον τύπο IAnimal, χωρίς να νοιαζόμαστε για τις λεπτομέρειες της υλοποίησης κάθε ζώου.
  1. Οφέλη της Ενθυλάκωσης και της Αφαίρεσης σε μεγαλύτερα προγράμματα

Όσο μεγαλύτερο γίνεται το πρόγραμμά σου, τόσο πιο σημαντική γίνεται η ενθυλάκωση και η αφαίρεση. Μερικά βασικά οφέλη που πρέπει να γνωρίζεις είναι:

Ευκολία στη συντήρηση: Ο κώδικας που ακολουθεί αυτές τις αρχές είναι ευκολότερος στη συντήρηση, γιατί οι αλλαγές σε μια κλάση δεν επηρεάζουν άλλα μέρη του προγράμματος.

Ευκολία στην κατανόηση: Η αφαίρεση κρύβει τις περίπλοκες λεπτομέρειες και καθιστά τον κώδικα ευκολότερο στην κατανόηση για άλλους προγραμματιστές που θα δουλέψουν με αυτόν.

Ασφάλεια δεδομένων: Η ενθυλάκωση προστατεύει τα ευαίσθητα δεδομένα και διασφαλίζει ότι χρησιμοποιούνται μόνο με τον σωστό τρόπο.

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

5. Συμπληρωματικές Έννοιες: Σταθερότητα Κώδικα και Τεστ

Η ενθυλάκωση και η αφαίρεση συμβάλλουν στο να γίνει ο κώδικας πιο σταθερός και να μπορούν να γράφονται εύκολα τεστ για τις λειτουργίες του προγράμματός σου.
Παράδειγμα:

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

Συμπέρασμα:

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

Αφαίρεση: Κρύβει τις περίπλοκες λεπτομέρειες της υλοποίησης και προσφέρει μια απλή και κατανοητή διεπαφή για τη χρήση των αντικειμένων.

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

Υπάρχουν μερικά ακόμα σημαντικά σημεία που συνδέονται με την Ενθυλάκωση (Encapsulation) και τα Αφηρημένα Δεδομένα (Abstraction) στην C#, τα οποία θα σε βοηθήσουν να αποκτήσεις ακόμα βαθύτερη κατανόηση αυτών των θεμελιωδών εννοιών.

  1. Το Σημαντικό του Κρυψίματος της Υλοποίησης (Implementation Hiding)

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

Αυτό είναι πολύ χρήσιμο γιατί:

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

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

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

Παράδειγμα Σύνθεσης:

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

csharp

class Engine
{
public void Start()
{
Console.WriteLine(“Η μηχανή ξεκινάει.”);
}
}

class Car
{
private Engine engine = new Engine();

public void StartCar()
{
    engine.Start();
    Console.WriteLine("Το αυτοκίνητο ξεκινάει.");
}

}

class Program
{
static void Main()
{
Car car = new Car();
car.StartCar(); // Το αυτοκίνητο ξεκινάει, χρησιμοποιώντας τη μηχανή
}
}

Αναλυτική Εξήγηση:

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

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

Μία κλάση, ένα πράγμα: Κάθε κλάση πρέπει να έχει έναν συγκεκριμένο σκοπό και να μην προσπαθεί να κάνει πολλά πράγματα ταυτόχρονα. Αν μια κλάση έχει πάρα πολλές λειτουργίες, αυτό σημαίνει ότι ίσως πρέπει να τη διασπάσεις σε μικρότερες κλάσεις.

Σαφής διάκριση αρμοδιοτήτων: Οι κλάσεις πρέπει να έχουν σαφείς ευθύνες και να μην ανακατεύονται με τις ευθύνες άλλων κλάσεων.
  1. Τα Getter και Setter Μέσα από τις Ιδιότητες

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

Υπάρχει ένα σημαντικό σημείο εδώ:

Χρησιμοποιώντας τα getter και setter μέσα από τις ιδιότητες, μπορείς να προσθέσεις ελέγχους ή άλλες λειτουργίες όταν τα δεδομένα αλλάζουν.

Παράδειγμα:

csharp

class Product
{
private decimal price;

public decimal Price
{
    get { return price; }
    set
    {
        if (value >= 0)
        {
            price = value;
        }
        else
        {
            Console.WriteLine("Η τιμή δεν μπορεί να είναι αρνητική.");
        }
    }
}

}

class Program
{
static void Main()
{
Product product = new Product();
product.Price = 50; // Εγκυρη τιμή
Console.WriteLine($”Η τιμή του προϊόντος είναι: {product.Price}”);

    product.Price = -5;  // Μη έγκυρη τιμή
}

}

Αποτέλεσμα:

Η τιμή του προϊόντος είναι: 50
Η τιμή δεν μπορεί να είναι αρνητική.

Το getter επιτρέπει την ανάγνωση της τιμής, ενώ το setter επιτρέπει την εγγραφή αλλά μόνο με προϋποθέσεις (π.χ., η τιμή δεν μπορεί να είναι αρνητική).
  1. Σχέση Ενθυλάκωσης και Τεστ Μονάδας (Unit Testing)

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

Αν δοκιμάζεις την κλάση BankAccount που είδαμε προηγουμένως, μπορείς να γράψεις τεστ για να ελέγξεις:

Αν το υπόλοιπο αυξάνεται σωστά όταν κάνεις κατάθεση.
Αν δεν μπορείς να κάνεις κατάθεση με αρνητικά ποσά.

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

  1. Το Σημαντικό του Λιγότερου Συμπλέγματος (Low Coupling)

Η ενθυλάκωση και η αφαίρεση συμβάλλουν στη μείωση του συμπλέγματος (coupling) ανάμεσα σε κλάσεις. Το συμπλέγμα είναι όταν μια κλάση εξαρτάται πολύ από άλλες κλάσεις.

Όσο λιγότερο εξαρτώνται οι κλάσεις μεταξύ τους, τόσο πιο ανεξάρτητες και εύκολες είναι στη συντήρηση.

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

Συμπέρασμα:

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