繁体   English   中英

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

[英]Why can't java find my method?

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

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

谢谢,

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 类型的原因是因为我希望能够传入各种 object 类型,每个类型都有一个 testing() 方法。

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

public interface Testable
{
   public void testing()
}

然后让myMethod()拿一个Testable

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

编辑:为了澄清,实现一个接口意味着 class 保证拥有该方法,但该方法可以为所欲为。 所以我可以有两个类,它们的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");
   }
}

问题是myMethod在实际运行之前无法知道它得到了 a b object。 你可以传入一个String ,因为它知道。

将其更改为

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

它应该可以工作。


问题更新:

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

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

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

你在说的是鸭子打字。 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();
  }
}

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

因为您传入的是 Object(b 继承自 Object)。 Object 没有测试,b 有。

在调用该方法之前,您可以传入 b 或将 object 转换为 b。

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

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

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

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

由于 Java 的设计方式。

Java 是“静态类型的” ,这意味着编译期间检查对象类型。

在 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 中执行此操作的“其他”方式正在反射地调用方法,但我不确定这是否是您需要的,因为当您这样做时代码更加抽象,但这就是自动化测试框架的方式(和许多其他框架(例如 Hibernate)确实有效。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM