Sobes.tech
Middle

Σημαίνει αυτό ότι η κλάση είναι αμετάβλητη αν έχει μια δημόσια ιδιότητα στην κλάση;

sobes.tech AI

Απάντηση από AI

Όχι.

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

Για να επιτευχθεί η αμεταβλητότητα, η κλάση πρέπει να πληροί τις ακόλουθες προϋποθέσεις:

  • Όλες οι ιδιότητες πρέπει να είναι ιδιωτικές (private) ή προστατευμένες (protected).
  • Δεν πρέπει να υπάρχουν setters (μέθοδοι που αλλάζουν τις τιμές των ιδιοτήτων).
  • Όλες οι εξαρτήσεις (αντικείμενα με τα οποία εργάζεται η κλάση) πρέπει επίσης να είναι αμετάβλητες ή η κατάσταση τους δεν πρέπει να αλλάζει από έξω.
  • Ο κατασκευαστής πρέπει να αρχικοποιεί πλήρως το αντικείμενο και δεν πρέπει να αλλάζει μετά τη δημιουργία.
  • Αν απαιτούνται αλλαγές, πρέπει να δημιουργούνται νέες περιπτώσεις του αντικειμένου με τις νέες τιμές.

Παράδειγμα μιας κλάσης με δημόσια ιδιότητα (μεταβλητή):

<?php
class MutableObject
{
    public $value; // Δημόσια ιδιότητα

    public function __construct($value)
    {
        $this->value = $value;
    }
}

$obj = new MutableObject(10);
echo $obj->value; // 10

$obj->value = 20; // Η τιμή άλλαξε από έξω
echo $obj->value; // 20

Παράδειγμα υλοποίησης μιας αμετάβλητης κλάσης:

<?php
class ImmutableObject
{
    private $value; // Ιδιωτική ιδιότητα

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function getValue() : int
    {
        return $this->value;
    }

    // Μέθοδος για "αλλαγή", στην πραγματικότητα δημιουργεί ένα νέο αντικείμενο
    public function withValue(int $newValue) : self
    {
        return new self($newValue);
    }
}

$obj1 = new ImmutableObject(10);
echo $obj1->getValue(); // 10

// $obj1->value = 20; // Σφάλμα: Δεν μπορεί να προσπελαστεί η ιδιωτική ιδιότητα

$obj2 = $obj1->withValue(20); // Δημιουργείται νέο αντικείμενο

echo $obj1->getValue(); // 10 (το αρχικό αντικείμενο δεν άλλαξε)
echo $obj2->getValue(); // 20 (νέο αντικείμενο με την τροποποιημένη τιμή)