【问题标题】:Why can't java find my method?为什么java找不到我的方法?
【发布时间】:2010-10-11 20:30:04
【问题描述】:

我正试图围绕 java 中的一些东西。当我将一个对象传递给另一个类的方法时,我可以不只调用该对象类固有的任何方法吗?

如下例等原因码无法编译的原因是什么?

谢谢,

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

编辑:我将 myMethod 中的参数保留为 Object 类型的原因是因为我希望能够传入各种对象类型,每个对象类型都有一个 testing() 方法。

【问题讨论】:

  • 作为一个好习惯,类名应该以大写字母开头。

标签: java class object methods


【解决方案1】:

为什么java找不到我的方法?

因为 Java 的设计方式。

Java 是"statically typed",这意味着在编译期间检查对象类型。

在 Java 中,只有当该方法属于该类型时,您才能调用该方法。

由于此验证是在编译期间进行的,并且 Object 类型没有“testing()”方法,因此编译失败(即使在运行时对象确实具有该方法”。这主要是为了安全。

其他人描述的解决方法将要求您创建一个新类型,您可以在其中告诉编译器

“嘿,这种类型的实例响应测试方法”

如果您想传递各种对象并使其保持通用性,一种方法是让这些对象实现和接口。

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

以后去别的地方

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

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

在 java 中执行此操作的“其他”方法是调用方法 reflectively,但我不确定这是否是您需要的,因为当您这样做时代码更加抽象,但仅此而已自动化测试框架(以及许多其他框架,如 Hibernate)实际上是如何工作的。

我希望这可以帮助您澄清原因。

【讨论】:

    【解决方案2】:

    问题是myMethod 在实际运行之前无法知道它正在获取b 对象。你可以传入String,就其所知。

    改成

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

    它应该可以工作。


    问题更新:

    编辑:我将 myMethod 中的参数保留为 Object 类型的原因是因为我希望能够传入各种对象类型,每个对象类型都有一个 testing() 方法。

    正如 Amanda S 和其他几个人所说,这是一个完美的界面案例。这样做的方法是创建一个定义testing() 方法的接口并更改myMethod 以获取实现该接口的对象。

    另一种解决方案(没有接口)是反思性地发现对象是否具有testing() 方法并调用它,但对于这样一个简单的情况,不建议这样做,也不需要这样做。

    【讨论】:

    • 啊,现在清楚一点了。我已经更新了这个问题,但是如果我想传入一个 a 或 c,每个对象都有自己的 testing() 方法,该怎么办?
    • 那么你应该声明它接受一个普通超类的参数。问题是java.lang.Object没有测试方法。
    • 呵呵,我稍微离开一下,回来发现问题改了,新问题有了更好的答案。哦,好吧。
    • @mmyers:可能先了解java的类型系统会更好。虽然我也写我自己。 :) 干杯
    【解决方案3】:

    如果你真的,真的想尽可能地保持参数抽象,你应该考虑反射 API。这样,您可以传递您想要的任何对象并动态执行您想要的方法。你可以看看some examples

    这不是唯一的方法,但根据您的问题,它可能是一种有效的替代方法。

    请记住,反射比直接调用您的方法要慢得多。您也可以考虑使用界面,例如 Amanda 帖子中的界面。

    【讨论】:

    • Quiza primeo deba de entender como funcionan las cosas en Java, y luego saltar a cosas más avanzadas。 :) 致敬!
    【解决方案4】:

    因为你传入了一个 Object(b 继承自 Object)。对象没有测试,b 有。

    您可以在调用方法之前传入 b 或将对象强制转换为 b。

    编辑 要传入实现该方法的泛型类:您需要创建一个具有方法签名的接口并传入接口类型而不是 Object。您传入的所有对象都必须实现该接口。

    【讨论】:

      【解决方案5】:

      如果您想通过testing() 方法传入各种对象,请让每个对象实现Testable 接口:

      public interface Testable
      {
         public void testing()
      }
      

      然后让myMethod() 接受Testable

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

      编辑:澄清一下,实现接口意味着类保证有方法,但方法可以做任何它想做的事。所以我可以有两个类,它们的testing() 方法做不同的事情。

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

      【讨论】:

      • 每个对象类的每个 testing() 方法都会不同。所以不可能有一种通用的测试方法。
      • “不同”是指不同的签名,还是只是其作用不同?如果只是实现不同,这仍然有效。
      • 它的作用不同。应用于该对象类型的“测试”在每个 class.testing() 方法中会有所不同。
      • @barfoon - 实际上,如果想传入“各种测试对象”,这是最好的方法。您将拥有一个每个类都必须实现的预期方法。即,当您的代码需要一个 Testable 对象时,您可以保证它会有一个 testing() 方法。
      • 课程必须公开吗?
      【解决方案6】:

      您只能访问对对象的引用类型可见的成员。

      myMethod(Object myObj) 的情况下,这意味着只有Object 中定义的成员,因此在class aclass b 的成员将不可见。

      如果您将a.myMethod 的定义更改为public static void myMethod(b myObj),您将能够在myMethod 中看到b 实例上的testing 方法。

      根据澄清更新:

      在这种情况下,为所有这些定义一个接口来实现可能是您想要的。

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

      【讨论】:

        【解决方案7】:

        您的问题是支持接口的经典论点。您希望尽可能通用,但您希望传递的每个对象都有一个 testing() 方法。我建议如下:

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

        【讨论】:

          【解决方案8】:

          你在说的是鸭子打字。 Java 没有鸭子类型。

          因此,您需要定义一个接口,所有具有testing() 方法的类都实现该接口。

          例如:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-08-30
            • 1970-01-01
            • 2021-09-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多