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

时间:2009-03-06 21:32:54

标签: java class object methods

我试图用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()方法。

8 个答案:

答案 0 :(得分:19)

如果您想使用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");
   }
}

答案 1 :(得分:8)

问题是myMethod在实际运行之前无法知道它正在获取b对象。你知道的所有内容都可以传递String

将其更改为

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

它应该有用。


更新问题:

  

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

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

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

答案 2 :(得分:6)

你所说的是鸭子打字。 Java没有鸭子打字。

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

e.g:

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

答案 3 :(得分:4)

您的问题是支持接口的经典论据。您希望尽可能通用,但是您希望传递的每个对象都有一个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" 
  }
}

答案 4 :(得分:2)

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

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

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

答案 5 :(得分:1)

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

如果myMethod(Object myObj)仅表示在对象中定义的成员,那么在class aclass b的成员将不会显示。

如果您将a.myMethod的定义更改为public static void myMethod(b myObj),则可以在testing中查看b实例上的myMethod方法}。

根据说明进行更新:

在这种情况下,为所有人实现定义接口可能就是你想要的。

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

答案 6 :(得分:1)

  

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

由于Java的设计方式。

Java是"statically typed",表示在编译期间检查对象类型。

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

由于此验证是在编译期间进行的,并且对象类型没有“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() );

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

我希望这有助于您澄清原因。

答案 7 :(得分:0)

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

这不是唯一的方法,但根据您的问题,它可能是一个有效的选择。

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