F 程式設計 物件導向程式設計之訪問修飾符

2021-05-17 21:33:19 字數 2703 閱讀 8631

封裝是類的一大特性,它把抽象的、複雜的事物封裝了在內部,呼叫者無法看到它的內部操作。然而,由於類的呼叫者能夠接觸到類暴露出來的任何屬性和方法,也能夠隨意的修改類的屬性,改變類的狀態,這也導致意外的bug出現。幸好,f#與.net其他的語言一樣,對於類的屬性和方法提供了可訪問控制,允許使用者可以操作哪些方法或者屬性。

f#的可訪問修飾符跟其它的.net語言一樣,提供了private、public、internal三種修飾符,但沒有了其它語言具有的protect。下面的示例新建了乙個類ruby類,類的訪問修飾符為internal,說明它只在所內的程式集內被其它類訪問,同時它的主建構函式為private,其它的建構函式為public:

type internal ruby private(shininess, carats) =

let mutable m_size = carats

let mutable m_shininess = shininess

member this.polish() =

this.size <- this.size - 0.1

m_shininess <- m_shininess + 0.1

member public this.size with get () = m_size

member private this.size with set newsize = m_size <- newsize

member this.shininess = m_shininess

public new() =

let rng = new random()

let s = float (rng.next() % 100) * 0.01

let c = float (rng.next() % 16) + 0.1

new ruby(s, c)

public new(carats) =

let rng = new random()

let s = float (rng.next() % 100) * 0.01

new ruby(s, carats)

在f#中,定義的型別、值、函式預設是public的,而類在字段(無論是let繫結還是val申明的)預設都是private的,下面的列出了三種訪問修飾符的作用以及使用範圍:

public:將乙個方法、屬性標記為可以在任何地方訪問,在f#中,如果型別、值、函式沒有任何標記訪問修飾符,預設都是public的

private:private限制了值、方法、屬性僅僅只能在類的內部訪問,也不能被外部訪問,就算是派生類也不行。類的字段預設是private的

internal:跟public修飾符一樣,但是它定義了只能被同一程式集內的型別所訪問,但不能被程式集外的任何型別訪問

可訪問修飾符不僅僅可以用於類,也可以用於模組,在模組中運用可訪問修飾符跟在類中是一樣的,例如:

open system.io

open system.collections.generic

module logger =

let mutable private m_filestowriteto = new list()

let addlogfile(filepath) = m_filestowriteto.add(filepath)

let logmessage(message : string) =

for logfile in m_filestowriteto do

use file = new streamwriter(logfile, true)

file.writeline(message)

file.close()

可訪問修飾符關鍵是作用範圍的限制和封裝,但是在每個型別、方法、值中增加訪問修飾符增加了很多混亂的**。控制整個**檔案訪問的最好的辦法就是使用f#的簽名檔案,它的副檔名是.fsi,允許你指定乙個完整的**檔案簽名,並且簽名檔案的檔名稱跟f#的**檔名稱是一樣的。任何方法、屬性在**檔案中,但是不在簽名檔案中的訪問修飾符都是private的。這提供了一種簡單方法來批量控制你的**的訪問。

下面顯示了乙個**檔案以及相應的簽名檔案,簽名檔案定義了乙個類的建構函式和兩個方法,在相應的**檔案中還有額外的屬性和方法。並且就算在**檔案中這些屬性和方法沒有被標記為private,但是編譯後的訪問修飾都是private的。如果沒有簽名檔案,那麼**檔案的成員都是public的。同時還需要注意的是,如果**檔案中的成員的訪問級別低於簽名檔案的訪問級別,那麼將會丟擲乙個異常:

//myclass.fsi

namespace myproject.utilities

type internal myclass =

new : unit -> myclass

member public property1 : int

member private method1 : int * int -> int

//myclass.fs

namespace myproject.utilities

type internal myclass() =

member this.property1 = 10

member this.property2 with set (x : int) = ()

member this.method1 (x, y) = x + y

member this.method2 () = true

PHP物件導向 訪問修飾符

php中有三種訪問修飾符,分別是 它們可以分別用在類的屬性和方法上 類的屬性和方法統稱為類的成員 用來修飾類成員的訪問許可權。public 公共的 預設 在php5中如果類沒有指定成員的訪問修飾符,預設就是public的訪問許可權。當類的成員被宣告為public的訪問修飾符時,該成員能被外部 訪問和...

PHP物件導向 訪問修飾符

php中有三種訪問修飾符,分別是 它們可以用在類的屬性和方法上,用來修飾類成員的訪問許可權,類的屬性和方法統稱為類的成員。在php5中如果類沒有指定成員的訪問修飾符,預設就是public的訪問許可權。以下兩個方法宣告訪問許可權效果相同 function test publilc function t...

訪問修飾符(C 程式設計指南)

所有型別和型別成員都具有可訪問性級別,用來控制是否可以在您程式集的其他 中或其他程式集中使用它們。您在宣告型別或成員時使用以下訪問修飾符之一來指定其可訪問性 public 同一程式集中的任何其他 或引用該程式集的其他程式集都可以訪問該型別或成員。private 只有同一類或結構中的 可以訪問該型別或...