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

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

如何在方法的使用和定義之間靈活地保留有用的對(duì)象功能?

如何在方法的使用和定義之間靈活地保留有用的對(duì)象功能?

四季花海 2023-10-13 10:01:40
說(shuō)明:假設(shè)我有這個(gè)簡(jiǎn)單的界面:interface Y { Y f(); }我可以通過(guò) 3 種不同的方式實(shí)現(xiàn)它:到處使用通用類型。class SubY_generalist implements Y{    public Y f()     {        Y y = new SubY_generalist();         ...        return y;     } }使用特殊類型,但返回相同的值,隱式轉(zhuǎn)換為通用類型。class SubY_mix implements Y{    public Y f()     {        SubY_mix y = new SubY_mix();         ...        return y;     } }使用特殊類型并返回相同的值。class SubY_specialist implements Y{    public SubY_specialist f()     {        SubY_specialist y = new SubY_specialist();         ...        return y;     } }我的考慮:這里附近有一個(gè)關(guān)于“接口編程”好處的長(zhǎng)篇對(duì)話。最受推崇的答案似乎并沒有深入探討參數(shù)類型和返回類型之間的區(qū)別,它們實(shí)際上是根本不同的。因此,我發(fā)現(xiàn)其他地方的討論并沒有給我一個(gè)明確的答案,我別無(wú)選擇,只能自己推測(cè)——當(dāng)然,除非好心的讀者能幫我一把。我將假設(shè)以下有關(guān) Java 的基本事實(shí):(它們正確嗎?)一個(gè)物體是在其最特殊的時(shí)候被創(chuàng)建的。它可以隨時(shí)隱式轉(zhuǎn)換為更通用的類型(廣義的) 。當(dāng)一個(gè)對(duì)象被泛化時(shí),它會(huì)失去一些有用的屬性,但不會(huì)獲得任何屬性。從這些簡(jiǎn)單的觀點(diǎn)來(lái)看,特殊物體比一般物體更有用,但也更危險(xiǎn)。例如,我可能有一個(gè)可變?nèi)萜?,我可以將其概括為不可變。如果我確保容器在被凍結(jié)之前具有一些有用的屬性,我可以在正確的時(shí)間對(duì)其進(jìn)行概括,以防止用戶意外破壞不變量。但這是正確的方法嗎?還有另一種方法可以實(shí)現(xiàn)類似的隔離:我可能總是將我的方法設(shè)為package-private。泛化似乎更靈活,但很容易被忽略,并為微妙的錯(cuò)誤引入一個(gè)表面。但在某些語(yǔ)言中,比如 Python,人們認(rèn)為沒有必要真正保護(hù)方法免受外部訪問(wèn);他們只是用下劃線標(biāo)記內(nèi)部方法。熟練的用戶可以訪問(wèn)內(nèi)部方法來(lái)獲得一些收益,只要他們了解所有的復(fù)雜性。另一個(gè)結(jié)果是,在方法定義中我應(yīng)該更喜歡專門的對(duì)象。 我的問(wèn)題:這是正確的想法嗎?我錯(cuò)過(guò)了什么嗎?這與接口編程的討論有何關(guān)系?這里的一些當(dāng)?shù)厝怂坪跽J(rèn)為這是相關(guān)的,我也同意這一點(diǎn),只是在我看來(lái)不是立即發(fā)生的。它更像是針對(duì)接口進(jìn)行編程,或者通常針對(duì)子類進(jìn)行編程。我對(duì)這些錯(cuò)綜復(fù)雜的事情有點(diǎn)不知所措。
查看完整描述

1 回答

?
慕村9548890

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

這是我用來(lái)談?wù)撛撝黝}的上下文。設(shè)函數(shù) f 有以下選項(xiàng):


interface Y { ... }

class SubY implements Y { ... }

DEFINITION CHOICE:

public SubY f() { ... }

OR

public Y f() { ... }

USAGE CHOICE:

...

Y y = f();

OR

SubY y = f(); //maybe with a cast

...

SubY從技術(shù)上講,所有選項(xiàng)都可以是正確的,具體取決于您是否打算向最終用戶(下一個(gè)程序員)    公開詳細(xì)信息。SubY如果向最終用戶公開看起來(lái)是個(gè)壞主意,那就不要這樣做。否則,就這樣做。推理如下:從概念上講,您應(yīng)該始終返回可能需要的最窄類型(較窄的類型位于類層次結(jié)構(gòu)

    的更下方- 將其視為“較窄的類型是較寬的類型”)。例如,如果您返回 a ,則意味著您希望最終用戶僅通過(guò)界面與其進(jìn)行交互。但是,如果您預(yù)計(jì)最終用戶將需要 中定義的交互,請(qǐng)返回該交互。     一般來(lái)說(shuō),這個(gè)想法是使方法的返回類型盡可能窄,而不暴露最終用戶不應(yīng)該知道的血腥細(xì)節(jié)。只要您正確隱藏類處理的內(nèi)部細(xì)節(jié),返回. 另一方面,考慮最終用戶的責(zé)任:     最終用戶的責(zé)任是負(fù)責(zé)任地使用狹窄的返回類型賦予他們的權(quán)力。您已經(jīng)通過(guò)正確隱藏內(nèi)部結(jié)構(gòu)來(lái)阻止他們做出令人討厭的事情。然后,當(dāng)最終用戶使用您的類時(shí),他們應(yīng)該根據(jù)自己的需求進(jìn)行編程,如下所示:ListArrayList

SubYSubY


// imported library provides:

public SubY f() { ... }

... // la la la

Y y = f();

useYFunctionality(y);

... // somewhere else that you need SubY functionality

SubY subY = f();

useSubYFunctionality(subY);

    因此,程序員應(yīng)該定義他們的函數(shù)來(lái)返回精確的類型,返回盡可能窄的安全實(shí)現(xiàn)(可以是一個(gè)接口)。另一方面,該服務(wù)/功能的最終用戶應(yīng)該將其變量定義為仍然有效的最廣泛的可能類型,以減少耦合并提高意圖的清晰度(如果這是您所需要的,請(qǐng)使用而getLicensePlateNumber不是Vehicle)VeryUnreliableCar。這里的關(guān)鍵是選擇返回類型沒有明確的答案。相反,請(qǐng)根據(jù)您的判斷來(lái)決定哪些內(nèi)容應(yīng)該暴露給最終用戶,哪些內(nèi)容不應(yīng)該暴露給最終用戶。如果沒有特殊原因拒絕訪問(wèn)SubY,請(qǐng)記住以下原則:Functions Return Accurately, Users Define Variables As Necessary或 FRAUDVAN。

    將其應(yīng)用到您的示例中:


class SubY_generalist implements Y

{

    public Y f()

    {

        Y y = new SubY_generalist();

        ...

        return y;

    }

}

到處使用接口。當(dāng)您只關(guān)心界面的細(xì)節(jié)時(shí),這是最好的,對(duì)于最終用戶來(lái)說(shuō)也是如此。例如,如果您只關(guān)心get和add,則Y可能是List,并且SubY_generalist()可能是ArrayList。

class SubY_mix implements Y

{

    public Y f()

    {

        SubY_mix y = new SubY_mix();

        ...

        return y;

    }

}

使用特定類型,但在返回時(shí)隱式擴(kuò)展為通用類型。當(dāng)您實(shí)際上需要使用特定類型的方法,但您的最終用戶永遠(yuǎn)不需要這樣做時(shí),這是最好的。使用前面示例中的ArrayList和,假設(shè)必須調(diào)用,一個(gè)未在 中定義的方法。那么,顯然有必要聲明為。但是,由于最終用戶只需要,因此您應(yīng)該返回并隱式擴(kuò)展。ListftrimToSizeListyArrayListListy

class SubY_specialist implements Y

{

    public SubY_specialist f()

    {

        SubY_specialist y = new SubY_specialist();

        ...

        return y;

    }

}

使用專用類型并返回專用類型。這就是FRAUDVAN的“本質(zhì)”。SubY_specialist由于返回類型允許用戶靈活地處理返回SubY_specialist,或者也可以使用f()接口方面的方式Y(jié)。當(dāng)接口不夠具體而無(wú)法有效使用時(shí)(它們應(yīng)該如此,因?yàn)樗鼈兪浅橄蟮模?,這是非常常見的。例如,在 Java類中,只要方法返回 a ,就會(huì)發(fā)生這種情況。這是因?yàn)閷?shí)施. 每當(dāng)您使用and 、、、或( Implements )時(shí),也會(huì)發(fā)生這種情況。     需要這種行為的原因是界面通常不包含最終用戶有效利用的足夠細(xì)節(jié)。將這些細(xì)節(jié)放在接口中會(huì)導(dǎo)致接口膨脹/污染,這是不可取的。相反,直接使用負(fù)責(zé)這些細(xì)節(jié)的類可以保留具有獨(dú)特功能的類的單一職責(zé)原則(避免被迫在接口的未來(lái)實(shí)現(xiàn)者中實(shí)現(xiàn)冗余)。畢竟,如果您的類實(shí)現(xiàn)了兩個(gè)接口,您要么必須創(chuàng)建一個(gè)擴(kuò)展這兩個(gè)接口的新接口并返回該接口(這很快就會(huì)變得丑陋),要么您可以返回實(shí)現(xiàn)者,并讓最終用戶負(fù)責(zé)他們需要哪個(gè)界面(不難看)。     為什么這種行為如此普遍?這是因?yàn)?,一旦隱藏了最終用戶不需要看到的東西(使用可見性修飾符、封裝和信息隱藏),讓最終用戶以他們選擇的方式與您的實(shí)現(xiàn)進(jìn)行交互實(shí)際上是一個(gè)好主意(即根據(jù)他們聲明變量的接口)。事實(shí)上,我什至聲稱這里的所有示例都符合 FRAUDVAN,其中向用戶公開的“最安全”類型而不是專用類型。在第一個(gè)示例中,界面對(duì)于用戶和最終用戶來(lái)說(shuō)足夠?qū)I(yè)化。在第二個(gè)示例中,對(duì)于用戶來(lái)說(shuō)不夠?qū)I(yè)化,但對(duì)于最終用戶來(lái)說(shuō)足夠?qū)I(yè)化。最后,在這個(gè)例子中,對(duì)于用戶和所有最終用戶來(lái)說(shuō)不夠?qū)iT化,盡管一些最終用戶可能選擇聲明是否適合他們的需要。StreamStreamStreamBaseStreamStringBufferreverseappendreplacedeleteinsertStringBufferCharSequence


YYYYY y = f()Y

所以,這是要點(diǎn):

https://img1.sycdn.imooc.com/6528a5540001c27402760151.jpg

查看完整回答
反對(duì) 回復(fù) 2023-10-13
  • 1 回答
  • 0 關(guān)注
  • 101 瀏覽
慕課專欄
更多

添加回答

舉報(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)