Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Java Discussion :

Classes, méthodes private


Sujet :

Java

  1. #1
    Membre habitué
    Inscrit en
    septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut Classes, méthodes private
    Bonjour,

    est-ce que quelqu'un pourrait m'expliquer quant il faut mettre les classes et méthodes private?
    Je voudrais aussi savoir l'intéret de mettre les constructeurs protected

    Merci

  2. #2
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    tout dépend de comment tu veux qu'on accède à ton code.

    Si tu veux qu'on puisse les instancier, appeler des méthodes dessus ...

    Public c'est pour que se soit accessible de partout
    Protected l'accès est réservé aux classes du meme package
    Private ben l'acces est interdit

    (j'espere que je ne me trompe pas)

    Pour ta question concernant le constructeur protected :

    et bien seulement les classes du meme package pourront instancier cet objet.
    Par exemple dans le cas d'une classe mère protected, une classe fille pourra utiliser le constructeur parent ... mais en dehors du package, aucune classe ne pourra instancier cet objet

    je sais pas si je suis clair, mais bon dans tous les cours sur java tu trouveras des explications sur la visibilité des objets ...
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

  3. #3
    Membre éprouvé
    Profil pro
    Architecte technique
    Inscrit en
    mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : mars 2002
    Messages : 966
    Points : 1 085
    Points
    1 085
    Par défaut
    Citation Envoyé par in
    tout dépend de comment tu veux qu'on accède à ton code.

    Si tu veux qu'on puisse les instancier, appeler des méthodes dessus ...

    Public c'est pour que se soit accessible de partout
    Protected l'accès est réservé aux classes du meme package
    Private ben l'acces est interdit

    (j'espere que je ne me trompe pas)[...]
    Malheureusement une erreur s'est glissée:

    public l'accés à une méthode public est garanti à toute classe.
    protected l'accés à une méthode protected est garanti à toute classe dans la package et toute sous-classe dans la hiérarchie d'héritage (et oui c'est bizarre).
    friendly (sans aucun modificateur) l'accés à une méthode friendly est garanti à toute classe dans la package.
    private l'accés est garanti à la classe où la méthode est définie uniquement.

    Les même régles s'appliquent quand un modificateur est placé devant un atrribut ou une définition de classe ou de classe interne.

    L'attribut static peut être combiné avec les modificateurs pré-cités pour permettre un accés à la méthode, classe interne ou attribut sans instance de classe.

    Il faut en général utiliser les modificateurs de la façon suivante:

    - private : quand on veut "masquer" un comportement d'un classe, un peu comme une boite noire, seul compte dans ce cas les entrées et la sortie.

    - protected est similaire à private mais dans le cas d'un héritage (pour que la méthode soit accéssible aux sous-classes)

    - friendly pour étendre la visibilité aux classes du package.

    - public pour tous.

    Alors à la lumière de ces constatations quelques régles générales se dégagent:
    - public est à utiliser avec parcimonie, le moins souvent possible.
    - toute méthode qui n'est accédée que dans la classe doit être définie private.
    - toute méthode qui n'est accédée que par la classe ou une de ses sous-classes doit être définie protected.
    - toute méthode accédée dans un package doit être définie friendly ou éventuellemet protected (mais moi je réserve protected aux cas d'héritage pour pas qu'il y ait de confusions).

    Ces régles sont applicables pour des classes internes et des attributs bien évidemment.

    Plus d'exemples pour apprendre à programmer avec Java voir les tutoriels et cours Java : http://java.developpez.com/cours/

    A+

  4. #4
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    en fait je parlait de la visibilité au niveau des classes.

    mais merci de tes explications qui sont bien plus utiles et claires que les miennes ...
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : juin 2006
    Messages : 194
    Points : 234
    Points
    234
    Par défaut
    Citation Envoyé par Premium
    Bonjour,

    est-ce que quelqu'un pourrait m'expliquer quant il faut mettre les classes et méthodes private?
    Je voudrais aussi savoir l'intéret de mettre les constructeurs protected

    Merci
    Seules les classes internes peuvent être déclarées private. On le fera lorsqu'aucune instance de cette classe interne n'a pas besoin d'être manipulée hors de la classe qui l'encapsule.

    Pareil pour les méthodes private. Il y a un élément supplémentaire, les appels de méthodes private ou final sont théoriquement plus rapides que les appels de méthodes public ou protected.

    Un constructeur, ou toute autre méthode, sera protected lorsqu'il est uniquement destiné à être redéfinie. Par exemple, on pourrait imaginer un Singleton dont on voudrait laisser la possibilité de redéfinir le constructeur. Attention néanmoins, l'utilisation de protected, contrairement à ce qu'on pourrait penser, n'est pas sûre car la visibilité peut être relevée à public lors de la redéfinition. protected doit donc être vu seulement comme une sorte de tag.

  6. #6
    Membre éprouvé
    Profil pro
    Architecte technique
    Inscrit en
    mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : mars 2002
    Messages : 966
    Points : 1 085
    Points
    1 085
    Par défaut
    Citation Envoyé par had35
    Seules les classes internes peuvent être déclarées private. On le fera lorsqu'aucune instance de cette classe interne n'a pas besoin d'être manipulée hors de la classe qui l'encapsule.
    Faux, une classe interne peut tout à fait être définie protected, public ou friendly.

    Citation Envoyé par had35
    Pareil pour les méthodes private. Il y a un élément supplémentaire, les appels de méthodes private ou final sont théoriquement plus rapides que les appels de méthodes public ou protected.
    Tout cela reste à prouver. Je ne suis pas certains quer la difference de traitement sur un appel d'une méthode de classe public ou privée soit significatif...

    A+

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 935
    Points : 22 988
    Points
    22 988
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par thibaut
    Faux, une classe interne peut tout à fait être définie protected, public ou friendly.
    Il ne dit pas le contraire !!! Il dit juste qu'une classe interne PEUT être private (ou protected d'ailleurs). Chose qu'on ne peut pas faire avec une classe "normal" (si une classe normal est private on ne pourrait l'utiliser nulle part).


    Citation Envoyé par thibaut
    Tout cela reste à prouver. Je ne suis pas certains quer la difference de traitement sur un appel d'une méthode de classe public ou privée soit significatif...
    Oui et non...

    En réalité l'appel d'une méthode public a un certain coût, puisque comme elle peut être redéfinit dans une classe fille, il faut vérifier le type réel de l'objet pour appeler la bonne méthode.

    Par exemple lorsqu'on fait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object o = new Integer(5);
    String s = o.toString();
    C'est bien la méthode toString() de Integer qui est appelé, et non pas celle de Object. C'est un appel de méthode dynamique, et ce type de fonctionnalité a un coût.

    A l'inverse les méthodes final ou private ne peuvent pas être redéfinit dans les classes filles. Donc la JVM n'a pas besoin de rechercher le type exact de l'objet et procède directement à un appel statique avec d'éventuelle optimisation (inlining de la méthode, etc.).


    Toutefois, la différence n'est vraiment visible que pour un très grand nombre d'appel de méthode, et surtout les JVM récentes (Java 1.2 et +) mettent en place plusieurs mécanismes d'optimisation :

    Comme la JVM s'occupe du chargement des classes, elle connaît exactement la hiérarchie des classes, et peut déterminer qu'une classe ne possède pas de classe fille, ou qu'une certaine méthode n'est jamais redéfinit dans ses classes filles. Elle peut donc optimiser les méthodes public de la même manière que les méthodes private ou final, en sachant que si une classe fille est chargée en mémoire, cela nécessiterai de recompiler le code...



    Le code suivant permet de mettre cela en évidence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    public class Main {
     
        private int privateMethod(int v) {
            return v + 1;
        }
     
        public final int publicFinalMethod(int v) {
            return v + 1;
        }
     
        public int publicMethod(int v) {
            return v + 1;
        }
     
        public void test() {
            int MAX = Integer.MAX_VALUE;
            long start, end;
     
            // Une boucle vide afin d'éviter que des optimisations
            // modifie les résultats du premier test 
            for (int i=0; i<MAX; i++) ;
     
            start = System.currentTimeMillis();
            for (int i=0; i<MAX; i++) {
                privateMethod(i);
            }
            end = System.currentTimeMillis();
            System.out.println("\tprivateMethod()       : " + (end-start));
     
     
            start = System.currentTimeMillis();
            for (int i=0; i<MAX; i++) {
                publicMethod(i);
            }
            end = System.currentTimeMillis();
            System.out.println("\tpublicMethod()        : " + (end-start));
     
     
            start = System.currentTimeMillis();
            for (int i=0; i<MAX; i++) {
                publicFinalMethod(i);
            }
            end = System.currentTimeMillis();
            System.out.println("\tpublicFinalMethod()   : " + (end-start));
        }
     
        public static void main(String[] args) {
     
            System.out.println("Test Direct :");
            new Main().test();
     
            System.out.println();
            System.out.println("Test avec une classe Fille :");
            new Main(){ // classe anonyme Main$1
                // Ne redéfinit pas la méthode publicMethod() !
                @Override
                public String toString() {
                    return "hello";
                }
            }.test();
     
            System.out.println();
            System.out.println("Test avec une classe Fille qui redéfinit publicMethod() :");
            new Main(){ // classe anonyme Main$2
                @Override
                public int publicMethod(int v) {
                    return 0;
                }
            }.test();
     
            System.out.println();
            System.out.println("Test Direct (bis) :");
            new Main().test();
        }
    }
    Pour rappel Integer.MAX_VALUE vaut quand même : 2147483647.

    J'obtiens les résultats suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Test Direct :
        privateMethod()       : 3672
        publicMethod()        : 3750
        publicFinalMethod()   : 3657
     
    Test avec une classe Fille :
        privateMethod()       : 3672
        publicMethod()        : 3765
        publicFinalMethod()   : 3657
     
    Test avec une classe Fille qui redéfinit publicMethod() :
        privateMethod()       : 3672
        publicMethod()        : 38986
        publicFinalMethod()   : 3687
     
    Test Direct (bis) :
        privateMethod()       : 3672
        publicMethod()        : 40063
        publicFinalMethod()   : 3703
    Lors du premier test, je n'ai qu'une classe de chargée (Main), et le temps d'exécution des boucles est quasiment identique à moins de 100 ms près.

    Dans le second test, j'ai deux classes chargées : Main et sa classe fille anonyme Main$1, et le test s'effectue sur cette dernière. Toutefois comme cette dernière ne surcharge pas la méthode publicMethod(), cela n'impacte quasiment pas les résultat.

    Dans le troisième test, j'ai une nouvelle classes anonymes de chargé : Main$2 qui redéfinit la méthode publicMethod(), cela oblige la machine virtuelle a vérifier dynamiquement le type réel de l'objet à chaque appel de la méthode. Du coup le temps d'exécution explose carrément et monte à près de 40 secondes contre un peu moins de 4 précédemment. On voit bien là le coût de l'appel dynamique...

    Enfin le quatrième test renouvelle un test avec la classe parente (Main), mais comme il y a plusieurs classes filles (Main$1 et Main$2) dont une redéfinit publicMethod(), l'appel dynamique est de nouveau utilisé, et on obtient les même résultat qu'au 3ieme test...


    Bref : les appels de méthode private et final sont plus rapide car il ne sont jamais exécuté en dynamique mais toujours en statique...
    Toutefois, la différence entre les deux est vraiment minime (environ 0.00002 ms si je ne me trompe pas) et ne se ressent que sur un très grand nombre d'appel de méthode (2 milliards en l'occurrence).


    a++

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : juin 2006
    Messages : 194
    Points : 234
    Points
    234
    Par défaut
    Merci adiGuba pour ces superbes précisions.
    Je vais moi aussi apporter une précision supplémentaire, bien que plus modeste

    J'ai simplifié un aspect de l'encapsulation des classes lorsque j'ai écrit ceci :
    Citation Envoyé par had35
    Seules les classes internes peuvent être déclarées private. On le fera lorsqu'aucune instance de cette classe interne n'a pas besoin d'être manipulée hors de la classe qui l'encapsule.
    En réalité, lorsqu'une classe interne est private, ce n'est pas réellement ses instances qui deviennents inaccessibles mais le type définit par la classe interne. Cela revient donc au même qu'écrire une classe anonyme (du moins concernant la visibilité du type), c'est-à-dire qu'une instance d'une classe interne private peut quand même être récupérée à condition qu'elle hérite d'une classe ou d'une interface publique.

    Un exemple ici : http://www.developpez.net/forums/sho...57&postcount=8

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/01/2008, 14h15
  2. Réponses: 3
    Dernier message: 08/12/2005, 15h41
  3. [FLASH MX2004] [AS2] Classe méthodes static
    Par bolo dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 16/12/2004, 19h26
  4. Débuts : classe / méthode main
    Par P@t dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 10/07/2004, 04h45
  5. [PL/SQL]Appel d'une classe/méthode java
    Par marsup54 dans le forum SQL
    Réponses: 4
    Dernier message: 30/06/2004, 17h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo