Qual è l'uso di modificatori di accesso dei membri meno restrittivi rispetto al modificatore di accesso alla classe?


9

Supponiamo che io abbia una classe con alcuni membri e che i membri abbiano un modificatore di accesso meno restrittivo della classe stessa.

Un esempio concreto potrebbe essere:

package apples;

class A { // package private
    public int foo() { // public (=> less restrictive than *package private*)
        return 42;
    }
}

Per quanto ne so, un modificatore di accesso di classe che è più restrittivo del modificatore di accesso dei membri , sostituirà i modificatori di accesso dei membri meno restrittivi . Quindi un modificatore di accesso membro meno restrittivo non dovrebbe avere alcun effetto.

  • La mia comprensione è corretta?
    • In caso contrario, quali sono le conseguenze?
  • Quali potrebbero essere i motivi validi per avere modificatori di accesso dei membri meno restrittivi?
  • Infine, quali sono le migliori pratiche da seguire?

Ho anche fatto alcuni esperimenti perché pensavo che potesse avere conseguenze una volta che avessi iniziato a passare i riferimenti alle funzioni, tuttavia anche allora il modificatore di accesso non sembra importare.

La situazione che ho costruito è la seguente:

  • apples.Bfornisce un metodo pubblico bla()che restituisce un riferimento a apples.A.foo.
  • Quindi pizzas.Cchiama apples.B.blaper ottenere un riferimento A.fooe lo chiama.
  • Quindi A.foo()non è direttamente visibile C, ma è accessibile solo indirettamente tramiteB.bla()

L'ho provato e non fa differenza se rendo foo() privato o meno il modificatore di accesso del pacchetto .

package apples;

import java.util.function.IntSupplier;

public class B {
    public IntSupplier getReferenceToAFoo() {
        A aInstance = new A();
        return aInstance::foo;
    }
}
package pizzas;

import apples.B;

import java.util.function.IntSupplier;

public class C {
    private int callAFooIndirectly() {
        B bInstance = new B();
        IntSupplier intsupplier = bInstance.getReferenceToAFoo();
        return intsupplier.getAsInt();
    }

    public static void main(String[] args) {
        C cInstance = new C();

        int i = cInstance.callAFooIndirectly();
        System.out.println(i);
        assert 42 == i;
    }
}

2
Il motivo più comune di gran lunga per questo tipo di progettazione è fornire implementazioni di metodi API pubblici (come quelli provenienti da interfacce o classi astratte estese) utilizzando classi non pubbliche. Lo stesso JDK è pieno di tali classi (es: java.util.Collections.SingletonSet<E>è privatein java.util.Collections).
ernest_k,

Risposte:


8

La mia comprensione è corretta?

Sì.

Quali potrebbero essere i motivi validi per avere modificatori di accesso dei membri meno restrittivi?

Due motivi:

  • A volte, stai implementando un'interfaccia; i metodi di interfaccia devono esserepublic
  • Rende più facile cambiare l'accesso generale della tua classe. Ad esempio, se contrassegni tutti i metodi che vorresti mai fossero pubblici public, anche in una classe pacchetto-privata, in seguito tutto ciò che devi fare per rendere pubblica la classe è aggiungere publicalla dichiarazione di classe.

Infine, quali sono le migliori pratiche da seguire?

Questa è una questione di opinione, quindi non adatta a una domanda o risposta Stack Overflow. Fai ciò che sembra ragionevole per te e / o il tuo team e / o fai quello che la guida di stile del tuo team ti dice di fare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.