需要参数扩展特定类并实现特定接口

时间:2010-09-01 19:06:32

标签: java scala interface multiple-inheritance

我有两个Java类层次结构,它们共享一个共同的祖先并实现一个通用接口。我需要将一个指针传递给另一个类中的方法。

interface I { ... }

class A extends java.awt.Component implements I { ... }
class B extends java.awt.Component implements I { ... }

class D {
  Component c;
  I i;
  void m(? x) {
    c = (Component) x;
    i = (I) x;
  }
}

我可以用“?”替换“A”,这样我就可以通过“B”或“x”传递?如果我将“java.awt.Component”投射到c并将其存储在“I”和i并将其存储在“class D { void m(java.awt.Component c, I i) { ... } } ”中,我就输了强打字的好处。

我需要申报

吗?
m(a, a)

并使用“m(b, b)”或“A a = new A(); B b = new B(); ”将其称为

abstract class C extends java.awt.Component implements I {...}

我无法创建

A

并将其传递,因为BC都不是JInternalFrame

顺便说一句,这可以在Scala中完成吗?

编辑:我要解决的实际问题是我有两个类,一个扩展JPanel,另一个扩展JInternalFrame。两者都是抽象的,并为其中显示的小部件提供了一些通用功能(用户可以编辑行,删除行等的JTable)。无论显示的基础对象类型如何,编辑和删除行的代码始终相同。我有几种方法允许用户单击一行,从弹出菜单中选择“删除”,并在请求确认后,删除所选的行和数据库对象,例如。有时我需要一个框架子组件,有时我需要一个面板子组件。我已经为该委托类型的每个抽象类中的公共功能和一个实例变量创建了一个委托类。然后,JPanelComponent派生类只是将实际实现推迟到委托。反过来,委托类需要一个指向“owner”类的指针,用于获取所选表行等的回调,以及指向{{1}的每个父级的“JOptionPane”性质的指针。确认对话框。

使用Java泛型方法非常有效。委托类现在被定义为<T extends Component & DelegateContainer上的泛型类,每个所有者抽象类都实现DelegateContainer(声明回调方法)。

如果我要在Scala中重写它,我可能会使用traits而不是创建委托类。例如,特征可以将删除功能“添加”到JInternalFrame派生的具体类中。

感谢您的快速回复。

3 个答案:

答案 0 :(得分:14)

拯救的泛型!

public class Test {
    public static void main(String... args){
        new D().m(new A());
        new D().m(new B());
    }
}

interface I {  }

class A extends java.awt.Component implements I {}
class B extends java.awt.Component implements I {}

class D {
  Component c;
  I i;
  <T extends java.awt.Component & I> void m(T x) {
    c = x;
    i = x;
  }
}

这不是真正做事的最佳方式,但在你的情况下它是有效的。您应该将方法分成两部分,一部分用于I行为,另一部分用于Component行为。

答案 1 :(得分:11)

这很难看,但你可以使用泛型并约束方法参数来扩展类并实现接口。这是一个完整的例子:

interface Foo {}

class Bar {}

class Impl extends Bar implements Foo {}

class D {

    private Foo foo;
    private Bar bar;

    <T extends Bar & Foo> void m(T t) {
        foo = t;
    }
}

public class Test {
    public static void main(String[] args) {
        Impl impl = new Impl();
        D d = new D();
        d.m(impl);
    }
}

我不知道这会如何适应Scala,我很害怕。


[按Rahul G编辑]

Scala方式是一样的。只是语法不同。

trait Foo
class Bar
class Impl extends Bar with Foo

class D {
  private var foo: Foo = _
  private var bar: Bar = _

  def m[A <: Bar with Foo](a: A) {
    foo = a
    bar = a
  }
}

object Main {
  def main(args: Array[String]) {
    val impl = new Impl
    val d = new D
    d.m(impl)
  }
}

答案 2 :(得分:4)

在这种情况下,如果你想按照你的描述去做,那么创建一个实现CA之间共同功能的类B可能是有意义的。 {1}}和A可以扩展。这样,您只需将类B作为参数传递给C方法。

如果不知道确切的类,很难明确地进行此调用。我只是基于你想要创建的功能。由于D.m方法显然需要能够对它们进行操作,因此必须有一些共同点。