簡體   English   中英

Java Generics - 使用extends關鍵字

[英]Java Generics - use of extends keyword

我閱讀了關於Java Generics的文檔,它說java'extends'關鍵字與Generics意味着和實現該接口的類。

基於此,我嘗試創建泛型類以進一步理解這一點。 這是我的示例代碼。

接口代碼:

package com.vipin.generics.doubtclear;

public interface DemoInterface1<T> {

    void display(T t);
}

現在,我創建了幾個實現此接口的簡單類:

package com.vipin.generics.doubtclear;

class myClass<T> implements DemoInterface1<T> {

    public myClass(T t) {

    }

    @Override
    public void display(T t) {
        System.out.println("Inside display method of myClass, object is ---> "+t);
    }
}

class myClass1<T> implements DemoInterface1<T> {

    public myClass1(T t) {

    }

    @Override
    public void display(T t) {
        System.out.println("Inside display method of myClass1, object is ---> "+t);
    }
}

這是具有main的類,它嘗試創建對象:

public class DoubtClear1 {

    static <T extends DemoInterface1<T>> void myFunc(T t) {
        t.display(t);
    }

    public static void main(String[] args) {

        myClass<Integer> iObj = new myClass<Integer>(1);
        myClass1<Integer> iObj1 = new myClass1<Integer>(1);
        DoubtClear1.myFunc(iObj);

    }
}
  • 在主要我創建myClass<Integer>myClass1<Integer>對象。

  • 根據我對'extends'關鍵字的理解,當應用於Generics時, myFunc()能夠獲取實現DemoInterface1接口的任何對象引用。

  • 這就是我在調用中所做的事情==> DoubtClear1.myFunc(iObj);

但是,這給了我編譯時錯誤:

The method myFunc(T) in the type DoubtClear1 is not applicable for the arguments (myClass<Integer>)

這真令人困惑。 我正在做關於這個主題的文檔中所寫的內容,但它失敗了。 我不確定我對這個主題的理解是否正確。

從我的感覺來看,泛型是令人困惑的,需要反復研究才能真正得到這個。

清除這一點的任何信息都非常感激。

目前您正在評估這一情況

static <myClass1<Integer> extends DemoInterface1<myClass1<Integer>> void myFunc(myClass1<Integer> t) {

這不是真的, myClass1<Integer>DemoInterface1<myClass1<Integer>>不匹配,因為myClass1 Integer泛型條件不是myClass1<Integer> (因為它是Integer )。

您應該執行以下操作

static <T> void myFunc(DemoInterface1<T> interface, T t) {
    interface.display(t);
}

因此,以下應該有效

myClass<Integer> iObj = new myClass<Integer>(1);

myClass1<Integer> iObj1 = new myClass1<Integer>(1);

DoubtClear1.myFunc(iObj, 1);

編輯:如果你想添加一個從DemoInterface1擴展的新接口,那將改變myFunc參數,如此

static <T, N extends DemoInterface1<T>> void myFunc(N interface, T t) {
    interface.display(t);
}

我假設最初是你想要的。

EDIT2:

代碼中的錯誤沒有發生,因為:

<T extends XYZ>

這確實意味着T實現或延伸自XYZ

錯誤是因為您使用它像這樣:

/*
    T extends from DemoInterface1, okay - this is myClass1 
       |
       |             the generic parameter of that 
       |             DemoInterface1 is bound to T, 
       |             which as mentioned, 
       |             extends from DemoInterface1 
       |             (in your case, it means this is myClass1<Integer>, NOT Integer)
       |                         |
       |                         |
       |                         |
       |                         |          here you receive a bound for T
       |                         |          where T is meant to extend from
       |                         |             DemoInterface1<T>
       |                         |          in your example, T is myClass1<Integer>, and NOT `Integer` that is the <T> of DemoInterface1<T> (myClass1<Integer>)
       |                         |              
       |                         |               |
      \|/                       \|/             \|/         */
static <T extends DemoInterface1<T>> void myFunc(T t) {
    t.display(t);
}

基本上, display方法接收的T不是Integer ,而是myClass1

EDIT3:

I got your point 
we have to pass object like myClass1<Integer> 
and NOT Integer. However, when we do like: 

myClass1<Integer> iObj1 = new myClass1<Integer>(1), 

isn't iObj1 of myClass1<Integer> type, and NOT Integer. 

This i am passing to myFunc(). 
Does <T> gets replaced with Integer? 
or with the object with which we are calling it? 
May be, this is the cause of confusion. 
Please explain. Thanks a lot!

是的,你給myFunc你的iObj1實例。 因此, static <T extends DemoInterface1<T>> void myFunc(T t) {<T> static <T extends DemoInterface1<T>> void myFunc(T t) {被解析為myClass1<Integer>

但是,您也將此作為t.display(__) display的參數。 因此,您嘗試將myClass1<Integer>賦予iObj1.display(__)的方法,但是等待Integer 基本上,你幾乎都在調用iObj1.display(iObj1) ,而display(T)等待Integer ,而不是myClass1<Integer>

你有這個功能:

static <T extends DemoInterface1<T> > void myFunc(T t) {
    t.display(t);
}

然后你這樣稱呼它:

myClass<Integer> iObj = new myClass<Integer>(1);
DoubtClear1.myFunc(iObj);

現在, myClass<Integer>與類型T extends DemoInterface1<T>不匹配T extends DemoInterface1<T>但類型T extends DemoInterface1<Integer> 所以也許你想要這樣的東西:

static <T extends DemoInterface1<?> > void myFunc(T t) {
    t.display(t);
}

那會有用。 (除非我誤解了你的意圖。)

暫無
暫無

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

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