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

有帮助吗?

解决方案

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

其他提示

问题是 myMethod 无法知道它在实际运行之前获取 b 对象。您可以传入 String ,因为它知道。

将其更改为

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

它应该有用。


更新问题:

  

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

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

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

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

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

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

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

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

对于 myMethod(Object myObj),只表示在Object中定义的成员,所以在 class a class b 的成员>将不可见。

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

根据说明进行更新:

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

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中,只有当该方法属于该类型时,才能调用方法。

由于此验证是在编译期间进行的,因此对象类型没有“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。这样,您可以传递任何您想要的对象并动态执行您想要的方法。您可以查看一些示例

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top