代码之家  ›  专栏  ›  技术社区  ›  arsenbonbon

在Java中重载方法使用更具体的数据类型

  •  2
  • arsenbonbon  · 技术社区  · 16 年前

    我有一些具有相同接口类型的不同对象的ArrayList,例如:

    Interface interface {}
    
    class A implements interface {}
    
    class B implements interface {}
    

    我还有一个重载方法,它实现接口的所有继承对象:

    public void doSomething(A obj) {}
    
    public void doSomething(B obj) {}
    

    编译器还强制我用接口编写重载方法:

    public void doSomething(interface obj) {}
    

    然后我遍历列表中的值并调用方法:

    for (interface obj: myList) {
       doSomething(obj);
    }
    

    既然obj的类型是“interface”,在obj实际上是b类型的情况下,调用dosomething(interface obj)而不是说dosomething(b obj)。

    我可以让Java做别的吗,所以当OBJ是A类型时,它调用DOOMEOTY(Objo)和ObjeObjices(B Objo),当OBJ是B类型的时候?

    5 回复  |  直到 16 年前
        1
  •  3
  •   Alexandre Brasil    16 年前

    Java使用早期绑定,这意味着Objo的类型是在编译期间定义的,而不是在运行时定义的。因为您的代码说obj是interface类型,所以编译器总是调用将interface作为参数的方法。

    您有两种选择使其调用正确的方法:

    1. (非常难看)在调用对象时使用instanceof和cast检查obj类型。

      for (interface obj: myList) {
         if(obj instanceof A)
            doSomething((A) obj);
         else if(obj instanceof B)
            doSomething((B) obj);
         else
            doSomething(obj); // Calls the method receiving Interface
      }
      
    2. 在接口中实现一个Visitor方法,这样A和B在被访问时都将调用方法dosomething(this)。

      interface Interface {
          void visit(OtherClass methodHolder);
      }
      
      class A implements Interface {
          public void visit(OtherClass methodHolder) {
              methodHolder.doSomething(this);
          }
      }
      
      class B implements Interface {
          public void visit(OtherClass methodHolder) {
              methodHolder.doSomething(this);
          }
      }
      
        2
  •  2
  •   Aviad Ben Dov    16 年前

    有一个诀窍。免责声明:很难看。

    如果使用剂量测量方法的类被称为类执行者,如:

    class Performer {
      void doSomething(A x);
      void doSomething(B x);
      void doSomething(Inf x);
    }
    

    您可以将以下内容添加到界面中:

    interface Ifc {
      void acceptPerformer(Performer p);
    }
    

    在A类和B类中,都是这样实现的:

    void acceptPerformer(Performer p) {
      p.doSomething(this);
    }
    

    并像这样实现剂量测量(ifc x)方法:

    void doSomething(Ifc x) {
      x.acceptPerformer(this);
    }
    

    这听起来很奇怪,但很管用。当调用接受接口的DoSomething方法时,它将在 混凝土类 . 当该类重新调用dosomething时,它将知道它是哪种类型,并将调用正确的dosomething!

        3
  •  0
  •   Bozho    16 年前

    这里的多态方法是定义 doSomthing() 在你 interface 并在 A 和 B ,然后在循环中调用它。根据具体对象,将运行不同的代码。

        4
  •  0
  •   Robin    16 年前

    方法是

    public void doSomething(interface obj)
    

    定义为接口的一部分?如果编译器强迫您编写方法,这是唯一有意义的。

    这就引出了一个问题,为什么您要尝试在实现中更改接口的方法签名。接口是一个关于对象外观的契约。

        5
  •  -1
  •   James Goodwin    16 年前

    你可以使用Java instanceof 运算符检查实现接口的类:

    if(obj instanceof A) {
        // do something
    } else {
        // do something else
    }
    

    但是一个更好的方法是拥有一个方法,该方法只接受您创建的接口实例中的任何对象,正如atmoCreations所提到的那样。