最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

第 85 講:C# 2 之訪(fǎng)問(wèn)器上的訪(fǎng)問(wèn)修飾符

2022-02-04 00:16 作者:SunnieShine  | 我要投稿

今天我們繼續(xù)來(lái)看語(yǔ)法新拓展。

Part 1 引例

盡管目前 C# 的封裝機(jī)制做得已經(jīng)很優(yōu)秀了,但仍然有極少數(shù)情況下,目前的語(yǔ)法做不到。

假設(shè)我有一個(gè)形狀的抽象類(lèi)型 Shape,然后派生出 Circle 圓形、Rectangle 矩形等等形狀的類(lèi)型。

假設(shè)我有一個(gè)屬性 Area 表示面積,用來(lái)計(jì)算面積數(shù)值。從另外一個(gè)層面,我們可以通過(guò)構(gòu)造器初始化 Area 來(lái)達(dá)到賦值的過(guò)程,就不用運(yùn)行時(shí)使用屬性的時(shí)候才來(lái)計(jì)算了:

可以看到,這樣的實(shí)現(xiàn)機(jī)制可以更加靈活地使用屬性:我們?yōu)?Area 屬性的 setter 設(shè)置了 protected 訪(fǎng)問(wèn)修飾符后,這個(gè)方法就只能用在當(dāng)前類(lèi)和它的派生類(lèi)型里使用賦值操作了。

在原來(lái),我們?nèi)绻@么書(shū)寫(xiě)代碼,就非常不合理:因?yàn)?setter 是 public 的,所以你完全可以隨便篡改數(shù)值。我們擁有了限制 setter 的訪(fǎng)問(wèn)修飾符,就可以多樣化使用屬性達(dá)到更深層次的封裝效果了。

Part 2 語(yǔ)法規(guī)則和細(xì)節(jié)

可以從前文的例子里看出,getter 和 setter 不必只通過(guò)屬性的訪(fǎng)問(wèn)修飾符單純作限制,而這個(gè)語(yǔ)法可以允許我們直接在 getset 關(guān)鍵字上訪(fǎng)問(wèn)修飾符。那么,這個(gè)語(yǔ)法有什么細(xì)節(jié)上的規(guī)則和限制呢?

2-1 不能同時(shí)使用兩次訪(fǎng)問(wèn)修飾符到兩個(gè)訪(fǎng)問(wèn)器上

試想一下這樣書(shū)寫(xiě)的代碼是什么意思:

這沒(méi)有任何限制的意義。一個(gè)屬性最多只有兩個(gè)不同的訪(fǎng)問(wèn)器(getter 和 setter 都叫屬性的訪(fǎng)問(wèn)器(Accessor)),你又同時(shí)給兩個(gè)訪(fǎng)問(wèn)器使用完全一樣的訪(fǎng)問(wèn)修飾符,那么,這不是就相當(dāng)于這種寫(xiě)法:

即直接把這個(gè)訪(fǎng)問(wèn)修飾符放在屬性上去。這不是一樣的嗎?

2-2 訪(fǎng)問(wèn)器設(shè)置的訪(fǎng)問(wèn)修飾符必須小于屬性本身的訪(fǎng)問(wèn)修飾符

這個(gè)說(shuō)法有點(diǎn)不好理解,舉個(gè)例子你就懂了。

假設(shè)我給屬性設(shè)置的是 protected 訪(fǎng)問(wèn)修飾符,那么它的 getter 或者 setter 的訪(fǎng)問(wèn)修飾符上就不能使用 public 這種修飾符。因?yàn)?public 意味著任何時(shí)候都可以使用,而 protected 僅用于派生類(lèi)型上。

假設(shè)這個(gè)語(yǔ)法合理的話(huà):

從兩個(gè)角度來(lái)說(shuō),public get 都沒(méi)有意義:

第一,publicprotected 范圍還大,那么這么限制顯然就沒(méi)有意義,因?yàn)閷傩员旧砭拖拗扑目稍L(fǎng)問(wèn)級(jí)別是只能派生類(lèi)型和自己類(lèi)型里可以看到。那么你設(shè)置 public 最多也就只能在這個(gè)范圍里面隨便使用這個(gè) getter。說(shuō)白了,getter 的訪(fǎng)問(wèn)級(jí)別是受到屬性這個(gè)語(yǔ)法本身的制約的。可問(wèn)題是這么做不就跟 protected 一樣嗎?那么寫(xiě)不寫(xiě)就無(wú)所謂了,因此 public get 沒(méi)有意義;

第二,public 修飾符如果真像是類(lèi)似 C# 標(biāo)準(zhǔn)語(yǔ)法那樣,允許在訪(fǎng)問(wèn)級(jí)別較小類(lèi)型里聲明使用訪(fǎng)問(wèn)級(jí)別較大的成員,實(shí)際上也不沒(méi)必要。因?yàn)?C# 語(yǔ)法確定和規(guī)定了屬性的訪(fǎng)問(wèn)模式是一個(gè)屬性名稱(chēng),帶上 getter 和 setter 的這么一個(gè)寫(xiě)法。那么超過(guò)屬性訪(fǎng)問(wèn)級(jí)別的訪(fǎng)問(wèn)器,按照屬性的語(yǔ)法規(guī)則,還不如不寫(xiě)訪(fǎng)問(wèn)修飾符。所以,這個(gè)角度來(lái)說(shuō),public get 也沒(méi)有意義。

總之,設(shè)置了一個(gè)超過(guò)屬性訪(fǎng)問(wèn)級(jí)別的訪(fǎng)問(wèn)修飾符到訪(fǎng)問(wèn)器上,是沒(méi)有意義的。因此,C# 并不允許你這么做。

2-3 訪(fǎng)問(wèn)器只有一個(gè)的時(shí)候,不能這樣加訪(fǎng)問(wèn)修飾符

這個(gè)比較好理解。如果一個(gè)屬性單純只有 getter 或者 setter 的時(shí)候,那么你往 getter 或 setter 上加訪(fǎng)問(wèn)修飾符的邏輯,就完全和在屬性上直接修改訪(fǎng)問(wèn)修飾符是等價(jià)的。所以,你這種時(shí)候去追加訪(fǎng)問(wèn)修飾符沒(méi)有任何意義,因此 C# 也不允許我們這么做。

比如這樣的語(yǔ)法,就是不合適的。

Part 3 帶不同修飾符的訪(fǎng)問(wèn)器的屬性的繼承和接口實(shí)現(xiàn)機(jī)制

屬性的語(yǔ)法到現(xiàn)在算是有了一個(gè)比較多樣化的升級(jí),那么它能否用于繼承和派生呢?答案是可以的。不過(guò)這里就需要注意一點(diǎn)細(xì)節(jié)了。下面我們來(lái)說(shuō)說(shuō),跟繼承派生相關(guān)的這種語(yǔ)法的用法和細(xì)節(jié)。

3-1 不能在提供重寫(xiě)的虛屬性和抽象屬性里出現(xiàn) private 訪(fǎng)問(wèn)器

考慮一種情況。假設(shè)我有這樣兩個(gè)類(lèi)型 CD

先不考慮 setter 怎么實(shí)現(xiàn)代碼,只關(guān)注于 setter 的訪(fǎng)問(wèn)修飾符的話(huà),你覺(jué)得,這個(gè) setter 的 private 修飾符合理嗎?可能你覺(jué)得,好像還蠻合理的,因?yàn)槟阒匦屡缮蛯?shí)現(xiàn)是在派生類(lèi)型里,而抽象屬性上的 setter 有 private,也只是邏輯上的一個(gè)限制。

實(shí)際上,不是這樣。屬性的任務(wù)是給字段提供賦值和取值的模式的。那么,屬性就只有三種狀態(tài):

  • 只有 getter:這種屬性多用于模擬和代替表示一個(gè)無(wú)參方法,比如 Shape 類(lèi)型給一個(gè) Area 方法來(lái)表示套公式以計(jì)算面積;

  • 只有 setter:這種屬性多用于規(guī)劃和隱式觸發(fā)事件(字段只有賦值操作,而 setter 可以封裝賦值和觸發(fā)事件的邏輯);

  • getter 和 setter 都有:這種屬性就更不用我多說(shuō)了,到處都有用。

而如果出現(xiàn) private 修飾符的訪(fǎng)問(wèn)器,就顯得非常沒(méi)有意義。private get 修飾的話(huà),這種一般只考慮出現(xiàn)在類(lèi)似剛才 Area 這種,只有 getter 的屬性。那么這種情況和剛才說(shuō)過(guò)的“只有一個(gè)訪(fǎng)問(wèn)器的屬性”是一樣的,因此它還不如將其定義為 private 的屬性;而 private set 的話(huà),它用作給對(duì)象的字段賦值。而本身字段的級(jí)別就比較低,低到什么程度呢?低到要么 private 要么 protectedinternalprotected internal 也有但很少。你想想,我在派生類(lèi)型上重寫(xiě)屬性的 setter 的時(shí)候,如果 private 修飾符允許的話(huà),那么為什么我不直接給這個(gè)字段賦值呢?字段本身就已經(jīng)低到內(nèi)部才能看到,而我卻繞了一個(gè)步驟用屬性去賦值,結(jié)果屬性的 setter 說(shuō)不定訪(fǎng)問(wèn)級(jí)別比直接給字段賦值還要低(比如我原本字段是在 C 類(lèi)型的,是 protected 修飾的,我有一個(gè) D 類(lèi)型從 C 類(lèi)型派生,結(jié)果屬性的賦值器卻用 private 給這個(gè)字段賦值)。你說(shuō),這有沒(méi)有起到封裝的目的和作用?顯然沒(méi)有嘛。

所以,在重寫(xiě)屬性(可能基類(lèi)型是抽象屬性,或者虛屬性)的時(shí)候,都不允許出現(xiàn) private 修飾的訪(fǎng)問(wèn)器。

3-2 不可變更從基類(lèi)型拿下來(lái)的待重寫(xiě)屬性的訪(fǎng)問(wèn)器的訪(fǎng)問(wèn)修飾符

這句話(huà)有點(diǎn)繞。舉個(gè)例子就明白了。

我有這么一個(gè)屬性,它是帶有兩個(gè)索引器需要我們重寫(xiě),一個(gè)是 getter,一個(gè)是 protected 修飾過(guò)的 setter。這種屬性在重寫(xiě)的時(shí)候,我們不能去更改 setter 的 protected 訪(fǎng)問(wèn)修飾符。因?yàn)槟憧赡軙?huì)把訪(fǎng)問(wèn)修飾符的范圍改小或改大。改得更小則破壞了面向?qū)ο蟮脑O(shè)計(jì)規(guī)則,再次派生的時(shí)候你都看不到它了;而改得更大了則暴露出了本來(lái)應(yīng)該封裝不讓外部看到的 setter,也破壞了面向?qū)ο蟮脑O(shè)計(jì)原則。所以,我們不能篡改修飾在訪(fǎng)問(wèn)器上的訪(fǎng)問(wèn)修飾符。

Part 4 它的用途

可以從前面給的例子里看出,這種機(jī)制似乎還不能和無(wú)法說(shuō)服我使用這個(gè)語(yǔ)法機(jī)制來(lái)處理一些字段的數(shù)據(jù)。這里我們來(lái)說(shuō)一下,封裝的靈活性。

我們?nèi)匀患僭O(shè) CD 類(lèi)型,并規(guī)定 _field 字段和 Field 屬性。

在這個(gè)代碼里,我們可以看到,我們盡量在減小 _field 的可訪(fǎng)問(wèn)級(jí)別,通過(guò)屬性來(lái)控制賦值和可訪(fǎng)問(wèn)情況,這樣字段就可以盡可能私有化起來(lái),使得封裝效果更為嚴(yán)格和嚴(yán)謹(jǐn)。

第 85 講:C# 2 之訪(fǎng)問(wèn)器上的訪(fǎng)問(wèn)修飾符的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
抚松县| 阳春市| 朔州市| 阿克陶县| 且末县| 寻甸| 米易县| 蓬莱市| 遂平县| 平阳县| 饶阳县| 固阳县| 大连市| 章丘市| 辉南县| 临邑县| 闻喜县| 天镇县| 女性| 嘉峪关市| 灌阳县| 盘锦市| 丰镇市| 门源| 巩义市| 大兴区| 苗栗县| 封丘县| 威远县| 阳江市| 岑溪市| 满城县| 绿春县| 炎陵县| 阿克苏市| 象州县| 岳普湖县| 米泉市| 丹东市| 华坪县| 周宁县|