web-dev-qa-db-fra.com

Méthodes publiques dans les classes de forfait-privé

Est-ce qu'il fait une différence pour marquer des méthodes comme public dans les classes packages-privées?

class SomePackagePrivateClass
{
    void foo();          // package private method

    public void bar();   // public method
}

Existe-t-il une différence pratique de la visibilité entre foo et bar ici?

42
fredoverflow

Si la classe ne sera pas prolongée par une autre sous-classe plus visible *, la seule différence est clarté de l'intention. Déclarant que toutes les méthodes package privé rendent plus difficile la détermination des futurs lecteurs pour déterminer lesquels des méthodes sont censées être appelées par d'autres classes dans le même paquet.

*ce qui n'aurait plus de sens qu'une solution de conception pour moi, mais techniquement est possible néanmoins.

20
Péter Török

Exemple utilisant l'héritage:

A.JAVA

package pkg1

class A {
  void foo();
  public void bar() {};
}

B.java

package pkg1

public class B extends A{

}

C.Java

package pkg2

public class C {
  public void doSomething() {
   B b = new B();
   b.bar(); //ok
   b.foo(); //won't work, since foo() is not visible outside of package 'pkg1'

   A a = new A(); //won't work since A is not visible outside of package 'pkg1'
   a.bar(); //won't work, since a cannot be created
  }
}
42
Thomas

Un autre cas où la méthode doit être public est lorsque vous créez une mise en œuvre privée de paquet de certaines classes ou interfaces publiques. Comme vous n'êtes pas autorisé à réduire la visibilité des méthodes remplacées, il faut être public.

10
Jörn Horstmann

Eh bien ... j'avais ce doute aussi (c'est pourquoi j'ai cherché ce fil). Cela pourrait être une bonne question.

Mais ...

Après une deuxième pensée, les choses sont vraiment plus simples que nous la pensions.

Une méthode package-privé est une méthode package private.

Semble absurde? Mais ...

Une méthode package-privé, même si sa classe est héritée, c'est toujours une méthode package-privé.

Cela a-t-il plus de sens maintenant? Pour une explication plus verbeuse:

Une méthode package-privée, même si sa classe est héritée par une sous-classe plus visible, c'est toujours une méthode package-privé.

[.____] Si la sous-classe est du même emballage, ces méthodes de paquet-privé sont également héritées, mais elles sont toujours package-privé .

Si la sous-classe est de l'emballage différent (d'ici, nous avons besoin de la classe mère pour être public, avec des méthodes de paquet privé), ces méthodes de paquet-privé sont non hérité (parce qu'ils ne sont pas visibles du tout).

[.____] Un point à noter, qui peut être la cause de ce doute, qu'une méthode package-privé dans une classe publique n'est pas visible en dehors de son emballage également.


Ce qui précède explique sur la méthode du paquet-privé. Et le cas de la méthode publique est la même chose.

Lorsqu'une classe package-privée est héritée par une sous-classe pubienne (du même paquet, ceci est un must), ses méthodes publiques sont héritées de méthodes publiques et devenaient donc des méthodes publiques dans une classe pubienne.

Dans l'exemple op, comme foo() et bar() sont à la fois dans une classe package-privée, leurs visibilités sont limitées à un package-privé à ce moment, jusqu'à ce que d'autres codes soient ajoutés (par exemple, héritage ).

J'espère que cela est suffisamment clair (et simple).

P.s. la table de contrôle d'accès Java

6
midnite

Cela fait très peu de différence, à moins que la classe ne soit prolongée par une classe publique (ou protégée imbriquée).

En tant que consistance, j'irais pour public. Il devrait être rare que des méthodes soient autrefois que public ou private.

Il existe un certain nombre d'exemples de méthodes publiques dans la classe privée Java.lang.AbstractStringBuilder. Par exemple, length() est public dans AbstractStringBuilder et est exposé dans la classe publique StringBuilder (remplacé par StringBuffer pour ajouter la synchronisation).

5

Oui. public Les méthodes d'une classe package-privée peuvent être utiles (bien qu'ils soient rares). Exemple illustratif de la Java Bibliothèque (et pris du livre classique "Efficace Java"):

Avez-vous déjà vu le Java.util.JumboEnumSet, Java.util.RegularEnumSet ?? Probablement pas, car ils sont privés et ne sont pas mentionnés dans la documentation.

Avez-vous déjà utilisé ?? Probablement oui. Ils sont retournés par la méthode statique de Java.util.EnumSet.noneOf(...). Bien que vous ne puissiez pas les construire vous-même, vous pouvez utiliser leurs méthodes publiques lorsqu'elles sont renvoyées de cette méthode.

La bonne chose à ce sujet est que vous ne savez pas lequel vous utilisez ou même qu'ils existent. Java décide lequel est plus efficace en fonction des arguments et peut utiliser une autre version différente. Vous n'accumulez que leur fonctionnalité en les faisant référence à travers leur interface commune (ce qui est un bon pratique quand même !!)

4
blue_note