Quelle est l'utilisation de modificateurs d'accès aux membres moins restrictifs que le modificateur d'accès aux classes?

9

Disons que j'ai une classe avec certains membres et que les membres ont un modificateur d'accès moins restrictif que la classe elle-même.

Un exemple concret pourrait être:

package apples;

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

À ma connaissance, un modificateur d'accès aux classes plus restrictif que le modificateur d'accès aux membres remplacera les modificateurs d'accès aux membres les moins restrictifs . Un modificateur d'accès aux membres moins restrictif ne devrait donc avoir aucun effet.

  • Ma compréhension est-elle correcte?
    • Sinon, quelles en sont les conséquences?
  • Quelles pourraient être des raisons valables d'avoir des modificateurs d'accès aux membres moins restrictifs?
  • Enfin, quelles sont les meilleures pratiques à suivre?

J'ai également fait des expériences parce que je pensais que cela pourrait avoir des conséquences une fois que je commencerais à transmettre des références de fonction, mais même dans ce cas, le modificateur d'accès ne semble pas avoir d'importance.

La situation que j'ai construite est la suivante:

  • apples.Bfournit une méthode publique bla()qui renvoie une référence à apples.A.foo.
  • Ensuite , les pizzas.Cappels apples.B.blapour obtenir une référence à A.fooet appelle.
  • Il A.foo()n'est donc pas directement visible C, mais n'est accessible qu'indirectement viaB.bla()

Je l'ai testé et cela ne fait aucune différence que je rende foo() privé ou non le modificateur d'accès du package .

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;
    }
}
Stefan D.
la source
2
La raison la plus courante de loin pour ce type de conception est de fournir des implémentations de méthodes API publiques (telles que celles provenant d'interfaces ou de classes abstraites étendues) en utilisant des classes non publiques. Le JDK lui-même regorge de telles classes (ex: java.util.Collections.SingletonSet<E>est privatededans java.util.Collections).
ernest_k

Réponses:

8

Ma compréhension est-elle correcte?

Oui.

Quelles pourraient être des raisons valables d'avoir des modificateurs d'accès aux membres moins restrictifs?

Deux raisons:

  • Parfois, vous implémentez une interface; les méthodes d'interface doivent êtrepublic
  • Cela facilite la modification de l'accès global de votre classe. Par exemple, si vous marquez toutes les méthodes que vous souhaitez voir publiques public, même dans une classe privée de package, alors tout ce que vous devez faire pour rendre la classe publique est d'ajouter publicà la déclaration de classe.

Enfin, quelles sont les meilleures pratiques à suivre?

C'est une question d'opinion, donc pas bien adaptée à une question ou une réponse Stack Overflow. Faites ce qui vous semble raisonnable et / ou votre équipe, et / ou faites ce que le guide de style de votre équipe vous dit de faire.

TJ Crowder
la source