Question

J'essaie de penser à quelque chose en Java. Lorsque je passe un objet à la méthode d'une autre classe, ne puis-je pas simplement appeler une méthode inhérente à cette classe d'objet?

Quel est le code raison tel que l'exemple ci-dessous ne compile pas?

Merci,

class a {
  public static void myMethod(Object myObj) {
    myObj.testing();
  }
}


class b {
  public void testing() {
    System.out.println ("TESTING!!!");
  }
}


class c {  
  public static void main (String[] args) {
    b myB = new b();    
    a.myMethod(myB);  
  }
}

Modifier: la raison pour laquelle j'ai laissé le paramètre dans myMethod sous le type Object, c'est parce que j'aimerais pouvoir transmettre divers types d'objet, chacun ayant une méthode testing ().

Était-ce utile?

La solution

Si vous souhaitez transmettre divers objets avec les méthodes testing () , demandez à chaque objet d'implémenter une interface Testable :

public interface Testable
{
   public void testing()
}

Demandez à myMethod () de prendre un Testable .

public static void myMethod(Testable testable)
{
  testable.testing();
}

Éditer: pour clarifier, l'implémentation d'une interface signifie que la classe est assurée d'avoir la méthode, mais que la méthode peut faire ce qu'elle veut. Je pourrais donc avoir deux classes dont les méthodes testing () font des choses différentes.

public class AClass implements Testable
{
   public void testing()
   {
      System.out.println("Hello world");
   }
}

public class BClass implements Testable
{
   public void testing()
   {
      System.out.println("Hello underworld");
   }
}

Autres conseils

Le problème est que myMethod ne peut pas savoir qu'il obtiendra un objet b jusqu'à ce qu'il soit réellement exécuté. Vous pouvez passer un String , pour autant qu'il sache.

Changez-le en

public static void myMethod(b myObj) {
  myObj.testing();
}

et cela devrait fonctionner.

Mise à jour de la question:

  

Modifier: la raison pour laquelle j'ai laissé le paramètre dans myMethod sous le type Object, c'est parce que j'aimerais pouvoir transmettre divers types d'objet, chacun ayant une méthode testing ().

Comme Amanda S et plusieurs autres l’ont dit, c’est le cas idéal pour une interface. Pour ce faire, vous devez créer une interface définissant la méthode testing () et modifier myMethod pour que les objets implémentant cette interface soient utilisés.

Une solution alternative (sans interfaces) consisterait à découvrir de manière réfléchie si l’objet a une méthode testing () et à l’appeler, mais cela n’est ni recommandé ni nécessaire pour un cas aussi simple.

Vous parlez de dactylographie. Java n’a pas de frappe de canard.

Par conséquent, vous devez définir une interface que toutes les classes utilisant une méthode testing () implémenteront.

exemple:

public interface Testable
{
   public void testing()
}

class B implements Testable 
{
  public void testing() {
    System.out.println ("TESTING!!!");
  }
}

class A {
  public static void myMethod(Testable myObj) {
    myObj.testing();
  }
}

Votre problème est un argument classique en faveur d’une interface. Vous voulez aussi générique que possible, mais vous voulez que chaque objet que vous transmettez ait une méthode testing (). Je suggère quelque chose dans le sens de ce qui suit:

public interface Testable
{
  public void testing();
}

public class A
{
  public static void myMethod(Testable myObj)
  {    
    myObj.testing();
  }
}

public class B implements Testable
{
  public void testing()
  {
    System.out.println("This is class B");
  }
}

public class C implements Testable
{
  public void testing()
  {
    System.out.println("This is class C");
  }
}

public class Test
{  
  public static void main (String[] args) 
  {
    B myB = new B();
    C myC = new C();
    A.myMethod(myB); // "This is class B"
    A.myMethod(myC); // "This is class C" 
  }
}

Parce que vous passez un objet (hérite de Object). L'objet n'a pas été testé, b en a.

Vous pouvez soit passer b, soit convertir l'objet en b avant d'appeler la méthode.

EDIT Pour passer dans une classe générique qui implémente cette méthode: vous voudrez créer une interface avec la signature de la méthode et transmettre le type d'interface au lieu de Object. Tous les objets que vous transmettez doivent implémenter l'interface.

Vous pouvez uniquement accéder aux membres visibles pour le type de référence que vous avez pour l'objet.

Dans le cas de myMethod (Object myObj) , cela signifie uniquement les membres définis dans Object, donc dans classe a les membres de classe b ne sera pas visible.

Si vous modifiez la définition de a.myMethod en public statique void myMethod (b myObj) , vous pourrez alors voir le testing sur l'instance de b en myMethod .

mettre à jour en fonction d'une clarification:

Dans ce cas, définir une interface à implémenter est probablement ce que vous souhaitez.

public interface Testable {
    public void testing();
}

public class a {
    public static void myMethod(Testable myObj) {
        myObj.testing();
    }
}

public class b implements Testable {
    public void testing () {
        System.out.println("TESTING!!!");
    }
}
  

Pourquoi & # 8217; ne parvient-il pas à trouver ma méthode?

En raison de la façon dont Java a été conçu.

Java est " Typiquement " , ce qui signifie que les types d'objets sont vérifiés pendant compilation.

En Java, vous ne pouvez appeler une méthode que si cette méthode appartient à ce type.

Etant donné que cette vérification est effectuée lors de la compilation et que le type d’objet n’a pas la valeur " testing () " méthode, la compilation échoue (même si, au moment de l'exécution, les objets utilisent cette méthode ". C’est principalement pour des raisons de sécurité.

La solution de contournement décrite par d’autres vous obligera à créer un nouveau type, dans lequel vous pourrez indiquer au compilateur

"Hé, les instances de ce type vont répondre à la méthode de test"

Si vous souhaitez transmettre une variété d’objets tout en les gardant génériques, vous pouvez notamment les implémenter et les mettre en interface.

public interface Testable { 
    public void testing();
}

class A implements Testable { // here this class commits to respond to "testing" message 
    public void testing() {
    }
}

class B implements Testable { // B "is" testable 
    public void testing() { 
        System.out.println("Testing from b");
    } 
}


class C implements Testable { // C is... etc. 
    public void testing() { 
        //.... 
    }
}

Plus tard, ailleurs

public void doTest( Testable object ) { 
    object.testing();
}

doTest( new A() );
doTest( new B() );
doTest( new C() );

Le " AUTRE " Pour ce faire, java appelle les méthodes de manière réflexive . , mais je ne suis pas sûr que ce soit ce dont vous avez besoin, car le code est beaucoup plus abstrait lorsque vous le faites de cette façon, mais c’est ainsi que fonctionnent les frameworks de tests automatisés (et beaucoup d’autres, comme Hibernate).

J'espère que cela vous aidera à clarifier la raison.

Si vous voulez VRAIMENT, VRAIMENT garder le paramètre aussi abstrait que possible, vous devriez envisager une API de réflexion. De cette façon, vous pouvez passer n'importe quel objet et exécuter dynamiquement la méthode que vous voulez. Vous pouvez consulter quelques exemples .

Ce n'est pas le seul moyen, mais cela pourrait être une alternative valable en fonction de votre problème.

N'oubliez pas que la réflexion est beaucoup plus lente que d'appeler directement vos méthodes. Vous pouvez également envisager d’utiliser une interface, telle que celle publiée dans le message d’Amanda.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top