Frage

Ich versuche, meine Gedanken um etwas in Java zu wickeln. Wenn ich ein Objekt in einer anderen Klasse Methode übergebe, kann ich nicht nur alle Methoden zu dieser Objektklasse eigen nennen?

Was ist der Grund, Code wie das folgende Beispiel nicht kompiliert?

Danke,

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);  
  }
}

Edit: Der Grund, warum ich die Parameter in myMethod als Typ Object verlassen habe, ist, weil ich in einer Vielzahl von Objekttypen übergeben können, möchte, die jeweils eine Prüfung () Methode .

War es hilfreich?

Lösung

Wenn Sie in einer Vielzahl von Objekten mit testing() Methoden weitergeben möchten, haben jeweils eine Testable Schnittstelle implementieren Objekt:

public interface Testable
{
   public void testing()
}

Dann haben myMethod() eine Testable nehmen.

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

Edit: Um zu klären, bedeutet eine Schnittstelle implementiert, dass die Klasse garantiert wird, um das Verfahren zu haben, aber die Methode kann tun, was er will. So konnte ich zwei Klassen hat, die testing() Methoden verschiedene Dinge tun.

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");
   }
}

Andere Tipps

Das Problem ist, dass myMethod nicht wissen kann, es ist ein b Objekt bekommen, bis es tatsächlich läuft. Sie könnten in einem String passieren, für alle weiß es.

Ändern Sie ihn auf

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

und es sollte funktionieren.


Update der Frage:

  

Edit: Der Grund, warum ich die Parameter in myMethod als Typ Object verlassen habe, ist, weil ich in einer Vielzahl von Objekttypen übergeben können, möchte, die jeweils eine Prüfung () Methode .

Wie Amanda S und mehr andere gesagt haben, ist dies ein perfekter Fall für eine Schnittstelle. Die Art und Weise, dies zu tun, ist eine Schnittstelle zu schaffen, die die testing() Methode und ändert myMethod definiert Objekte zu nehmen, die eine Schnittstelle zu implementieren.

Eine alternative Lösung (ohne Schnittstellen) wäre reflektiv herauszufinden, ob das Objekt eine testing() Methode hat und es nennen, aber dies wird nicht empfohlen und nicht für einen solchen einfachen Fall erforderlich.

Was Sie sprechen, ist Ente eingeben. Java nicht Ente eingeben haben.

Sie benötigen daher eine Schnittstelle zu definieren, die alle Klassen mit einer testing() Methode implementieren.

z:

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();
  }
}

Ihr Problem ist ein klassisches Argument für eine Schnittstelle. Sie wollen so allgemein wie möglich, aber Sie wollen, dass jedes Objekt, das Sie eine Test () -Methode haben passieren. Ich schlage vor, etwas entlang der Linien der folgenden Optionen:

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" 
  }
}

Weil Sie in einem Objekt vorbei (b erben von Object). Objekt nicht getestet haben, b der Fall ist.

Sie können in b entweder übergeben oder das Objekt geworfen b, bevor Sie die Methode aufrufen.

EDIT Um in einer allgemeinen Klasse übergeben, der diese Methode implementiert: Sie wollen eine Schnittstelle bilden, die die Methode Signatur und übergeben Sie in der Interface-Typ anstelle von Object. Alle Objekte, die Sie in passieren muss die Schnittstelle implementieren.

Sie können nur die Mitglieder zugreifen, die für die Art der Referenz Sie auf das Objekt haben sichtbar sind.

Im Fall von myMethod(Object myObj), die nur die definierten Elemente in Object bedeutet, so in class a die Mitglieder class b nicht sichtbar sein wird.

Wenn Sie die Definition von a.myMethod geändert zu werden public static void myMethod(b myObj) Sie dann in der Lage sein würden, die testing Methode auf der Instanz von b während in myMethod zu sehen.

Update basiert auf Klarstellung:

In diesem Fall eine Schnittstelle für alle von ihnen definieren, wahrscheinlich zu implementieren ist, was Sie wollen.

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!!!");
    }
}
  

Warum Java kann nicht meine Methode finden?

Aufgrund der Art und Weise Java entwickelt wurde.

Java ist "statisch typisierte" das heißt Objekte werden Typen geprüft bei Kompilation.

In Java können Sie eine Methode aufrufen, nur dann, wenn das Verfahren zu diesem Typ gehört.

Da diese Überprüfung während der Kompilierung und der Objekttyp hat gemacht wird nicht die „Prüfung ()“ Methode, schlägt die Kompilierung (auch wenn zur Laufzeit, wenn die Objekte tun haben, dass die Methode“. Dies in erster Linie für die Sicherheit ist.

Die Abhilfe, wie von anderen beschrieben benötigen Sie eine neue Art zu erstellen, in dem Sie den Compiler kann sagen,

"Hey, die Instanzen dieses Typs reagieren, um die die Testmethode"

Wenn Sie eine Vielzahl von Objekten übergeben wollen und halten es sehr allgemein, eine Möglichkeit, diese Objekte mit implementieren und die Schnittstelle.

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() { 
        //.... 
    }
}

Später woanders

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

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

die "andere" Art und Weise, dies zu tun, in Java ist die Methoden

Wenn Sie wirklich, wirklich die Parameter so abstrakt wie möglich halten wollen, sollten Sie Reflection-API berücksichtigen. Auf diese Weise können Sie passieren, was Objekt, das Sie wollen, und führen Sie dynamisch die Methode, die Sie wollen. Sie können einen Blick auf einige Beispiele .

Es ist nicht die einzige Art und Weise, aber es könnte eine gute Alternative je nach Problem sein.

Beachten Sie, dass Reflexion ist viel langsamer als direkt Ihre Methoden aufrufen. Sie sollten erwägen auch über eine Schnittstelle, wie die auf Amandas Post.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top