Sobes.tech
Junior

Cos'è un modificatore di accesso 'protected' in un linguaggio di programmazione e in quali casi dovrebbe essere usato?

sobes.tech AI

Risposta dell'AI

protected — è un modificatore di accesso che consente ai membri di una classe (campi, metodi) di essere accessibili all'interno della stessa classe, nelle classi derivate (anche se si trovano in un pacchetto diverso) e in tutte le classi dello stesso pacchetto.

Applicazione:

Viene utilizzato quando si desidera fornire accesso ai membri della classe solo ai suoi eredi e ad altre classi nello stesso pacchetto, nascondendoli al mondo esterno al di fuori di questo pacchetto e della gerarchia di ereditarietà.

Esempi di scenari di utilizzo:

  • Quando la classe padre contiene campi o metodi che fanno parte della sua implementazione interna, ma sono necessari per espandere la funzionalità nelle classi derivate.

    public class Animal {
        protected String name; // Accessibile agli eredi e alle classi nello stesso pacchetto
    
        protected void eat() { // Accessibile agli eredi e alle classi nello stesso pacchetto
            System.out.println(name + " sta mangiando.");
        }
    }
    
    public class Dog extends Animal {
        public void bark() {
            System.out.println(name + " sta abbaiando."); // Accesso al campo protected name
            eat(); // Accesso al metodo protected eat()
        }
    }
    
  • Quando in un pacchetto c'è un gruppo di classi strettamente correlate, e si richiede che abbiano accesso agli elementi interni l'una dell'altra, ma nascondendoli alle classi di altri pacchetti. In questo caso, protected funziona in modo simile al modificatore di default (package-private) per le classi nello stesso pacchetto, ma apre anche l'accesso agli eredi di qualsiasi pacchetto.

    // Pacchetto com.example.core
    package com.example.core;
    
    public class BaseConfig {
        protected int threshold = 10; // Accessibile alle classi in com.example.core e agli eredi di qualsiasi pacchetto
    }
    
    // Pacchetto com.example.app (può essere in un altro pacchetto)
    package com.example.app;
    
    import com.example.core.BaseConfig;
    
    public class AppConfig extends BaseConfig {
        public void displayThreshold() {
            System.out.println("Threshold: " + threshold); // Accesso al campo protected da un altro pacchetto
        }
    }
    
    // Pacchetto com.example.core
    package com.example.core;
    
    public class RelatedConfig {
         public void printBaseThreshold(BaseConfig config) {
             System.out.println("Base Threshold da RelatedConfig: " + config.threshold); // Accesso al campo protected nello stesso pacchetto
         }
    }
    

Evita l'uso eccessivo di protected, poiché può complicare il refactoring e violare l'incapsulamento, consentendo agli eredi o alle classi nello stesso pacchetto di manipolare direttamente lo stato interno dell'oggetto. È preferibile usare private con metodi getter/setter pubblici, se l'ereditarietà diretta e l'accesso all'implementazione interna non sono l'obiettivo principale.