淺談 Nim 中的“接口”



      本篇文章是作者在看Nim 標準庫源碼時受到啓發而寫的,在Nim 官網的教程和手冊上沒有找到interface的相關說明,“接口” 這個說法是從Java類比過來的,現在還不能確定Nim 是否有接口,但interface在Nim中是保留關鍵字。

     下面是我寫的一段代碼:

type  
  Person* = ref PersonObj
  PersonObj* = object of RootObj  
    speakImpl*: proc (p: Person)   
    eatImpl*: proc (p: Person)  
  
proc showSpeak*(p: Person) =   
  p.speakImpl(p)  
  
proc showEat*(p: Person) =   
  p.eatImpl(p)  
  
  
type  
  Chinese* = ref ChineseObj
  ChineseObj* = object of Person  
  
proc Cspeak*(p: Person) =  
  echo ("你好")  
proc Ceat*(p: Person) =   
  echo ("饅頭")  
  
proc newChinese*(): Chinese =  
  new(result)
  result.speakImpl = Cspeak  
  result.eatImpl = Ceat  
  
  
type  
  American* = ref AmericanObj 
  AmericanObj* = object of PersonObj  
    
proc Aspeak*(p: Person) =   
  echo ("Hello")  
  
proc Aeat*(p: Person) =   
  echo ("hamburger")  
  
proc newAmerican*(): American =   
  new(result)
  result.speakImpl = Aspeak  
  result.eatImpl = Aeat  
  
  
  
var   
  varC = newChinese()  
  varA = newAmerican()  
  
varC.showSpeak()  
varA.showSpeak()  
varC.showEat()  
varA.showEat()

        在上面的程序中type定義了一個“接口”,Person是類PersonObj的引用,PersonObj中有兩個過程,分別是speakImpl和eatImpl,這兩個就相當與Java中的接口方法,下面定義的兩個類型Chinese和American分別實現了這個“接口”。過程newChinese和newAmerican的作用是對“接口”中的過程的實現,最後我們的對象能夠調用經過封裝的“接口”的過程。其實我們也可以可以直接調用“接口”中的過程,而不需要封裝成showSpeak和showEat。例如:

varC.speakImpl(varC)
varA.speakImpl(varA)
varC.eatImpl(varC)
varA.eatImpl(varA)

     你也可以不使用引用類型,直接用一個類,下面的這段代碼也是可以的:

type
  Person* = object of RootObj
    speak*: proc (p: Person) 
    eat*: proc (p: Person)

proc showSpeak*(p: Person) = 
  p.speak(p)

proc showEat*(p: Person) = 
  p.eat(p)


type
  Chinese* = object of Person

proc Cspeak*(p: Person) =
  echo ("你好")
proc Ceat*(p: Person) = 
  echo ("饅頭")

proc newChinese*(): Chinese =
  result.speak = Cspeak
  result.eat = Ceat


type
  American* = object of Person
  
proc Aspeak*(p: Person) = 
  echo ("Hello")

proc Aeat*(p: Person) = 
  echo ("hamburger")

proc newAmerican*(): American = 
  result.speak = Aspeak
  result.eat = Aeat



var 
  varC = newChinese()
  varA = newAmerican()

varC.showSpeak()
varA.showSpeak()
varC.showEat()
varA.showEat()


       這裏並沒有像Java那樣有關鍵字interface標記,當然,你也可以把Chinese 、American 和測試文件寫在不同的文件裏。這是在看的標準庫 Nim\lib\pure\streams 裏看到的,源碼介紹說是提供了 stream 接口。有興趣的同學可以看看。




      本篇文章是作者在看Nim 標準庫源碼時受到啓發而寫的,在Nim 官網的教程和手冊上沒有找到interface的相關說明,“接口” 這個說法是從Java類比過來的,現在還不能確定Nim 是否有接口,但interface在Nim中是保留關鍵字。

     下面是我寫的一段代碼:

type  
  Person* = ref PersonObj
  PersonObj* = object of RootObj  
    speakImpl*: proc (p: Person)   
    eatImpl*: proc (p: Person)  
  
proc showSpeak*(p: Person) =   
  p.speakImpl(p)  
  
proc showEat*(p: Person) =   
  p.eatImpl(p)  
  
  
type  
  Chinese* = ref ChineseObj
  ChineseObj* = object of Person  
  
proc Cspeak*(p: Person) =  
  echo ("你好")  
proc Ceat*(p: Person) =   
  echo ("饅頭")  
  
proc newChinese*(): Chinese =  
  new(result)
  result.speakImpl = Cspeak  
  result.eatImpl = Ceat  
  
  
type  
  American* = ref AmericanObj 
  AmericanObj* = object of PersonObj  
    
proc Aspeak*(p: Person) =   
  echo ("Hello")  
  
proc Aeat*(p: Person) =   
  echo ("hamburger")  
  
proc newAmerican*(): American =   
  new(result)
  result.speakImpl = Aspeak  
  result.eatImpl = Aeat  
  
  
  
var   
  varC = newChinese()  
  varA = newAmerican()  
  
varC.showSpeak()  
varA.showSpeak()  
varC.showEat()  
varA.showEat()

        在上面的程序中type定義了一個“接口”,Person是類PersonObj的引用,PersonObj中有兩個過程,分別是speakImpl和eatImpl,這兩個就相當與Java中的接口方法,下面定義的兩個類型Chinese和American分別實現了這個“接口”。過程newChinese和newAmerican的作用是對“接口”中的過程的實現,最後我們的對象能夠調用經過封裝的“接口”的過程。其實我們也可以可以直接調用“接口”中的過程,而不需要封裝成showSpeak和showEat。例如:

varC.speakImpl(varC)
varA.speakImpl(varA)
varC.eatImpl(varC)
varA.eatImpl(varA)

     你也可以不使用引用類型,直接用一個類,下面的這段代碼也是可以的:

type
  Person* = object of RootObj
    speak*: proc (p: Person) 
    eat*: proc (p: Person)

proc showSpeak*(p: Person) = 
  p.speak(p)

proc showEat*(p: Person) = 
  p.eat(p)


type
  Chinese* = object of Person

proc Cspeak*(p: Person) =
  echo ("你好")
proc Ceat*(p: Person) = 
  echo ("饅頭")

proc newChinese*(): Chinese =
  result.speak = Cspeak
  result.eat = Ceat


type
  American* = object of Person
  
proc Aspeak*(p: Person) = 
  echo ("Hello")

proc Aeat*(p: Person) = 
  echo ("hamburger")

proc newAmerican*(): American = 
  result.speak = Aspeak
  result.eat = Aeat



var 
  varC = newChinese()
  varA = newAmerican()

varC.showSpeak()
varA.showSpeak()
varC.showEat()
varA.showEat()


       這裏並沒有像Java那樣有關鍵字interface標記,當然,你也可以把Chinese 、American 和測試文件寫在不同的文件裏。這是在看的標準庫 Nim\lib\pure\streams 裏看到的,源碼介紹說是提供了 stream 接口。有興趣的同學可以看看。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章