簡體   English   中英

需要參數擴展特定類並實現特定接口

[英]Requiring an argument extends a particular class AND implements a particular interface

我有兩個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 {...}

並傳遞它,因為AB都不是C

順便說一句,這可以在Scala中完成嗎?

編輯:我想解決的實際問題是我有兩個類,一個擴展JInternalFrame ,另一個擴展JPanel 兩者都是抽象的,並為其中顯示的小部件提供了一些通用功能(用戶可以編輯行,刪除行等的JTable)。 無論顯示的基礎對象類型如何,編輯和刪除行的代碼始終相同。 我有幾種方法允許用戶單擊一行,從彈出菜單中選擇“刪除”,並在請求確認后,刪除所選的行和數據庫對象,例如。 有時我需要一個框架子組件,有時我需要一個面板子組件。 我已經為該委托類型的每個抽象類中的公共功能和一個實例變量創建了一個委托類。 然后, JInternalFrameJPanel派生類將實際實現推遲到委托。 反過來,委托類需要一個指向“owner”類的指針,用於獲取所選表行等的回調,以及指向JOptionPane確認對話框的每個父級的“ Component ”性質的指針。

使用Java泛型方法非常有效。 委托類現在被定義為<T extends Component & DelegateContainer上的泛型類,每個所有者抽象類都實現DelegateContainer (聲明回調方法)。

如果我要在Scala中重寫它,我可能會使用traits而不是創建委托類。 例如,特征可以將刪除功能“添加”到JInternalFrame派生的具體類中。

感謝您的快速回復。

通用的救援!

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行為。

這很難看,但你可以使用泛型並約束方法參數來擴展類並實現接口。 這是一個完整的例子:

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

在這種情況下,如果你想為你描述的事情,它可能有必要創建一個類C實現之間的共同功能AB從兩個AB可以延長。 這樣,您可以將類C作為參數傳遞給Dm方法。

如果不知道確切的類,很難明確地進行此調用。 我只是基於你想要創建的功能。 由於Dm方法顯然需要能夠對兩者進行操作,因此必須有一些共同點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM