簡體   English   中英

在Java中聲明類和接口的Member變量

[英]Declare a Member variable of both a class and interface in Java

我有一個帶有構造函數的類,該構造函數接受一個參數,該參數必須是Context類(或任何子類), 實現Alertable接口。 我將使用此參數設置一個成員變量,該成員變量隨后將在整個類中用作Context實例或Alertable實例。

public <T extends Context & Alertable> ApiGateway(T context)
{
     // Constructor code here
}

我如何可以聲明一個成員變量mAlertableContext ,使得它也兼具類的Context和實現接口Alertable

我嘗試將通用定義粘貼在代碼中的各個位置,但是它們始終會出現語法錯誤。 理想情況下,我想有像一個成員變量<T> mAlertableContext或類似的東西,在哪里可以治療mAlertableContext無論是作為ContextAlertable

我想出的一種(非常糟糕的)解決方法是聲明兩個成員變量,一個為Context類型,另一個為Alertable類型,並將它們分配給相同的構造函數參數,並與我需要它們的類/接口對象一起使用參加ApiGateway

private Context mContext;
private Alertable mAlertable;

public <T extends Context & Alertable> ApiGateway(T context)
{
    mContext = context;
    mAlertable = context;
}

我真的希望有一種更好的方法來執行此操作,因為它顯然是重復數據。

ApiGateway的角度來看,我喜歡使用一個“ mAlertableContext”成員變量的ApiGateway 無論如何,都需要定義如何處理AlertableContext 在創建“ mAlertableContext”變量時,特別需要您創建AlertableContext對象的組合的定義。

我認為最好的辦法是遵循AJB的意見建議,並創建一個AlertableContext該類ApiGateway 摘要如何結合的細節AlertableContext從客場ApiGateway ,並把這些細節到AlertableContext -在有需要時方知的基礎上, ApiGateway並不需要知道你是如何定義的組合AlertableContext 將該定義留給AlertableContext類。

AlertableContext類中具有Alertable變量 Context變量是有意義的,因為AlertableContext本身定義了其對象可以是另一個對象,因此AlertableContext的兩個變量充當方法及其實現之間的映射。 AlertableContext變量是對同一對象的引用,因此不會有兩個對象占用內存空間。 它們只是映射定義。

public class ApiGateway {

    private AlertableContext mAlertableContext;

    public <T extends Context & Alertable> ApiGateway(T context) {
        // Constructor code here
        mAlertableContext = new AlertableContext(context);
    }

    public void doAnApiCall() {

        // now the Context and Alertable members are available from mAlertableContext
        mAlertableContext.alert();
        mAlertableContext.doAContextThing();
    }
}

class AlertableContext extends Context implements Alertable {

    private Context context;
    private Alertable alertable;

    <T extends Context & Alertable> AlertableContext(T alertableContext) {
        this.context = alertableContext;
        this.alertable = alertableContext;
    }

    // override Context methods
    @Override
    public void doAContextThing() {
        context.doAContextThing();
    }

    // required from Alertable
    public void alert() {
        alertable.alert();
    }
}

如果您不喜歡單獨的變量,我知道還有一個選擇-轉換。 您可以避免使用單獨的AlertableContext對象,並使用一個Object類型的對象。 我個人認為這有點令人困惑,但是應該可以。

class AlertableContext extends Context implements Alertable {

    private Object alertableContext;

    <T extends Context & Alertable> AlertableContext(T alertableContext) {
        this.alertableContext = alertableContext;
    }

    // override Context methods
    @Override
    public void doAContextThing() {
        ((Context) alertableContext).doAContextThing();
    }

    // required from Alertable
    public void alert() {
        ((Alertable) alertableContext).alert();
    }
}

您的代碼請求將<T>提升為類類型參數:

  1. 您要求輸入一個成員字段<T>
  2. 您正在構造器中傳遞此<T>

因此,它看起來像:

// you can compile this snippet:

class Context {}
interface Alertable {};

class ApiGateWay<T extends Context & Alertable> {

   private final T myContext;

   ApiGateWay(T context) {
     myContext = context;
   }
}

然后,您可以像這樣實例化ApiGateWays

// you CANNOT compile this snippet:

class ContextX extends Context implements Alertable { ... }
...
ContextX ctx = ...;
...
ApiGateWay<ContextX> agwX = new ApiGateWay<>(ctx);

暫無
暫無

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

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