IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Langage Java Discussion :

héritage et instrospection


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de scorbo
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 176
    Par défaut héritage et instrospection
    Bonjour,

    C'est pas vraiment un problème mais plus une question. Je vais essayer d'expliquer clairement ma situation. J'ai une classe mère qui a la méthode "callMethod" qui permet de faire une rétroinspection pour lancer lancer la méthode dont le nom est passé en argument. La méthode "callMethod" est protected.
    Ensuite j'ai une classe fille qui hérite de la première et qui fait appel à la méthode de la classe mère "callMethod". Et les méthode que je cherche sont dans la classe fille. Mon interrogation porte sur le fait qu'il ne trouve les méthodes qu'à condition qu'elles soient déclarées public et non protected ou private.
    On pourrait se dire que c'est normal puisque les méthodes de la classe fille ne sont pas accessibles depuis une classe mère, mais lorsque je demande à voir d'où vient l'appelle de la méthode il me dis bien qu'il vient de la classe fille, et c'est là que je ne comprend pas la subtilité du mécanisme.

    Avec une illustration ça sera surement plus clair:

    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
     
    public class Mere {
     
        protected Object callMethod(Object obj, Object[] args, String methodName) throws Exception {
    		Class[] paramTypes = null;
    		if(args != null) {
    			paramTypes = new Class[args.length];
    			for(int i=0;i<args.length;++i) {
    				paramTypes[i] = args[i].getClass();
    			}
    		}
    		Method m = obj.getClass().getDeclaredMethod(methodName, paramTypes);
    		return m.invoke(obj, args);
    	}
     
    }
     
     
    public class fille extends mere {
        public void test() {
            callMethod(this, null, "maFonction");
        }
     
       public void maFonction() {
          System.out.println("maFonction");
       }
    }
    donc ma question est : pourquoi faut-il déclarer obligatoirement "maFonction" comme étant public pour que l'utilisation de "callMethod" fonctionne, sinon il ne la trouve pas.

  2. #2
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 890
    Par défaut
    Salut,

    Pourquoi passer "this" à ta méthode ?
    Etant donné que tu l'utilises uniquement dans les classes qui étendent Mere, tu peux ne pas le passer, et directement utiliser "this" dans le corps de la méthode.

    C'est peut-être là qu'il y a un problème.

    A+

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    962
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 962
    Par défaut
    Probablement parce que la classe Class ne peut pas avoir accès aux méthodes privées ou protégées d'une autre classe.

    (Je pense que le code qu'il a fourni n'est qu'un exemple, KiLVaiDeN.)

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par BugFactory
    Probablement parce que la classe Class ne peut pas avoir accès aux méthodes privées ou protégées d'une autre classe.
    +1

    L'appel de méthode via la reflection respectent les mêmes règles que si la méthode était appellé directement. Ainsi une classe mère ne peut pas appeller une méthode private d'une de ses classes filles, ni les méthodes protected ou "package-view" sauf si les deux classes font partie du même package (voir Que signifient les mots-clés public, private et protected ?signal_si_nouveau(conv_date("19/07/2004"));signal_si_mise_a_jour(conv_date(""))


    Mais tu peux forcer l'appel de méthode en utilisant setAccessible() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            Method m = obj.getClass().getDeclaredMethod(methodName, paramTypes);
            m.setAccessible(true);
            return m.invoke(obj, args);
    a++

  5. #5
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut
    invoke

    public Object invoke(Object obj,
    Object... args)
    throws IllegalAccessException,
    IllegalArgumentException,
    InvocationTargetException

    Invokes the underlying method represented by this Method object, on the specified object with the specified parameters. Individual parameters are automatically unwrapped to match primitive formal parameters, and both primitive and reference parameters are subject to method invocation conversions as necessary. If the underlying method is static, then the specified obj argument is ignored. It may be null.
    If the number of formal parameters required by the underlying method is 0, the supplied args array may be of length 0 or null.
    If the underlying method is an instance method, it is invoked using dynamic method lookup as documented in The Java Language Specification, Second Edition, section 15.12.4.4; in particular, overriding based on the runtime type of the target object will occur.
    If the underlying method is static, the class that declared the method is initialized if it has not already been initialized.
    If the method completes normally, the value it returns is returned to the caller of invoke; if the value has a primitive type, it is first appropriately wrapped in an object. However, if the value has the type of an array of a primitive type, the elements of the array are not wrapped in objects; in other words, an array of primitive type is returned. If the underlying method return type is void, the invocation returns null.

    Parameters:obj - the object the underlying method is invoked fromargs - the arguments used for the method call
    Returns:the result of dispatching the method represented by this object on obj with parameters args
    Throws:
    IllegalAccessException - if this Method object enforces Java language access control and the underlying method is inaccessible.
    IllegalArgumentException - if the method is an instance method and the specified object argument is not an instance of the class or interface declaring the underlying method (or of a subclass or implementor thereof); if the number of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal parameter type by a method invocation conversion.
    InvocationTargetException - if the underlying method throws an exception.
    NullPointerException - if the specified object is null and the method is an instance method.
    ExceptionInInitializerError - if the initialization provoked by this method fails.

  6. #6
    Membre confirmé Avatar de scorbo
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 176
    Par défaut
    Merci pour toutes ces réponses.

    adiGuba :
    Effectivement lorsque je rajoute un "setAccessible" ça fonctionne, j'avais déjà essayé cette solution.
    Mais là où je bloque c'est sur le fait que l'exception qu'il me génère lorsqu'il ne trouve pas la méthode appelée (parce qu'elle a été déclarée private ou protected) indique qu'il appelle la méthode "callMethod" depuis la classe fille et non depuis la classe mère, même si elle appartient à cette dernière.
    Donc moi je me dis : s'il appelle la méthode "callMethod" depuis la classe fille, alors pourquoi il ne trouve pas la méthode recherchée puisqu'elle lui appartient.
    Mais sinon, je comprend bien le pourquoi de cette erreur, c'est juste le message d'erreur qui est quelque peu perturbant.

    Note : Effectivement les classes mère et fille sont dans le même package donc je pourrais utiliser une déclaration de la méthode recherchée sans mot clé (public, private, ou protected). Je ne connaissais pas cette solution, merci !

Discussions similaires

  1. [Postgresql]Héritage
    Par lheureuxaurelie dans le forum PostgreSQL
    Réponses: 13
    Dernier message: 02/10/2008, 09h18
  2. [Héritage] Vos commentaires....
    Par Fyna dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 03/05/2005, 22h10
  3. [XML Schemas]héritage multiple
    Par nicolas_jf dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 10/06/2003, 12h55
  4. [Postgres] Héritage + Clés
    Par k-reen dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 21/05/2003, 16h37
  5. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 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