第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

用簡(jiǎn)單的英語(yǔ)解釋協(xié)方差,不變性和相反性?

用簡(jiǎn)單的英語(yǔ)解釋協(xié)方差,不變性和相反性?

猛跑小豬 2019-11-21 12:49:48
今天,我讀了一些有關(guān)Java中協(xié)方差,協(xié)方差(和不變性)的文章。我閱讀了英文和德文的Wikipedia文章,以及其他來(lái)自IBM的博客文章和文章。但是我對(duì)這些到底是什么還是有些困惑?有人說(shuō)這與類型和子類型之間的關(guān)系有關(guān),有人說(shuō)與類型轉(zhuǎn)換有關(guān),有人說(shuō)它用于確定方法是被重寫還是被重載。因此,我正在尋找一種簡(jiǎn)單易懂的英語(yǔ)解釋,它向初學(xué)者展示了協(xié)方差和逆方差(和不變性)。加號(hào)是一個(gè)簡(jiǎn)單的例子。
查看完整描述

3 回答

?
犯罪嫌疑人X

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊

有人說(shuō)這與類型和子類型之間的關(guān)系有關(guān),有人說(shuō)與類型轉(zhuǎn)換有關(guān),還有人說(shuō)它用于確定方法是被覆蓋還是被重載。


上述所有的。


本質(zhì)上,這些術(shù)語(yǔ)描述了類型轉(zhuǎn)換如何影響子類型關(guān)系。也就是說(shuō),如果A和B是類型,f則是類型轉(zhuǎn)換,并且≤子類型關(guān)系(即A ≤ B表示A是的子類型B),我們有


f是協(xié)變的,如果A ≤ B暗示f(A) ≤ f(B)

f是矛盾的,如果A ≤ B暗示f(B) ≤ f(A)

f 如果以上兩個(gè)都不成立,則是不變的

讓我們考慮一個(gè)例子。讓f(A) = List<A>哪里L(fēng)ist聲明


class List<T> { ... } 

是f協(xié)變,逆變還是不變?協(xié)變意味著a List<String>是的子類型List<Object>,相反,a List<Object>是的子類型,List<String>并且不變都不是另一個(gè)的子類型,即List<String>和List<Object>是不可轉(zhuǎn)換的類型。在Java中,后者是正確的,我們說(shuō)(某種程度上是非正式的)泛型是不變的。


另一個(gè)例子。讓f(A) = A[]。是f協(xié)變,逆變還是不變?也就是說(shuō),String []是Object []的子類型,Object []是String []的子類型,還是兩者都不是子類型?(答案:在Java中,數(shù)組是協(xié)變的)


這仍然很抽象。為了更加具體,讓我們看一下Java中的哪些操作是根據(jù)子類型關(guān)系定義的。最簡(jiǎn)單的例子是分配。該聲明


x = y;

僅在時(shí)才編譯typeof(y) ≤ typeof(x)。也就是說(shuō),我們剛剛了解到


ArrayList<String> strings = new ArrayList<Object>();

ArrayList<Object> objects = new ArrayList<String>();

不會(huì)在Java中編譯,但是


Object[] objects = new String[1];

將。


子類型關(guān)系很重要的另一個(gè)示例是方法調(diào)用表達(dá)式:


result = method(a);

非正式地說(shuō),該語(yǔ)句是通過(guò)將a方法的值分配給方法的第一個(gè)參數(shù),然后執(zhí)行方法的主體,然后將方法的返回值分配給來(lái)評(píng)估的result。就像最后一個(gè)示例中的普通分配一樣,“右側(cè)”必須是“左側(cè)”的子類型,即,僅當(dāng)typeof(a) ≤ typeof(parameter(method))和時(shí),此語(yǔ)句才有效returntype(method) ≤ typeof(result)。也就是說(shuō),如果方法通過(guò)以下方式聲明:


Number[] method(ArrayList<Number> list) { ... }

以下任何表達(dá)式都不會(huì)編譯:


Integer[] result = method(new ArrayList<Integer>());

Number[] result = method(new ArrayList<Integer>());

Object[] result = method(new ArrayList<Object>());


Number[] result = method(new ArrayList<Number>());

Object[] result = method(new ArrayList<Number>());

將。


子類型很重要的另一個(gè)示例是重載??紤]:


Super sup = new Sub();

Number n = sup.method(1);

哪里


class Super {

    Number method(Number n) { ... }

}


class Sub extends Super {

    @Override 

    Number method(Number n);

}

非正式地,運(yùn)行時(shí)會(huì)將其重寫為:


class Super {

    Number method(Number n) {

        if (this instanceof Sub) {

            return ((Sub) this).method(n);  // *

        } else {

            ... 

        }

    }

}

為了編譯標(biāo)記行,覆蓋方法的方法參數(shù)必須是覆蓋方法的方法參數(shù)的超類型,返回類型必須是覆蓋方法的子類型。從形式上來(lái)講,f(A) = parametertype(method asdeclaredin(A))必須f(A) = returntype(method asdeclaredin(A))至少是協(xié)變的,如果必須至少是協(xié)變的。


請(qǐng)注意上面的“至少”。這些是任何合理的靜態(tài)類型安全的面向?qū)ο缶幊陶Z(yǔ)言都將強(qiáng)制執(zhí)行的最低要求,但是編程語(yǔ)言可能會(huì)選擇更嚴(yán)格的標(biāo)準(zhǔn)。對(duì)于Java 1.4,在覆蓋方法(即parametertype(method asdeclaredin(A)) = parametertype(method asdeclaredin(B)),覆蓋)時(shí),參數(shù)類型和方法返回類型必須相同(類型擦除除外)。從Java 1.5開始,重寫時(shí)允許使用協(xié)變返回類型,即以下內(nèi)容將在Java 1.5中進(jìn)行編譯,但在Java 1.4中不進(jìn)行編譯:


class Collection {

    Iterator iterator() { ... }

}


class List extends Collection {

    @Override 

    ListIterator iterator() { ... }

}

我希望我覆蓋了所有內(nèi)容,或者更確切地說(shuō),是劃傷了表面。我仍然希望它將有助于理解類型差異的抽象但重要的概念。


查看完整回答
反對(duì) 回復(fù) 2019-11-21
  • 3 回答
  • 0 關(guān)注
  • 548 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)