日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

duck typing java_编程语言中的鸭子类型 Duck Typing

發布時間:2025/3/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 duck typing java_编程语言中的鸭子类型 Duck Typing 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來源 |?https://segmentfault.com/a/1190000019607240

1、什么是鴨子類型(duck typing)

百度百科是這樣解釋的:

這是程序設計中的一種類型推斷風格,這種風格適用于動態語言(比如PHP、Python、Ruby、Typescript、Perl、Objective-C、Lua、Julia、JavaScript、Java、Groovy、C#等)和某些靜態語言(比如Golang,一般來說,靜態類型語言在編譯時便已確定了變量的類型,但是Golang的實現是:在編譯時推斷變量的類型),支持"鴨子類型"的語言的解釋器/編譯器將會在解析(Parse)或編譯時,推斷對象的類型。

有沒有感覺很難理解?下面我們就來用通俗的語言介紹一下鴨子類型(Duck Typing)。

如果一只動物走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只動物就可以被稱為鴨子。

許多編程語言都支持 Duck Typing ,通常 Duck Typing 是動態編程語言用來實現多態的一種方式。

在理解 Duck Typing 前,先看一張圖片,這是曾經一度很火的大黃鴨

先問一個比較考三觀的問題:圖片中的大黃鴨,它是不是一只鴨子呢?

這個問題,得看你從哪個角度去看,如果從人們常識的認知中的角度去看,它顯然不是一只鴨子,因為它連最基本的生命都沒有。

但是從 Duck Typing 的角度來看,它就是一只鴨子!

Duck Typing 的原話是,走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么它就是一只鴨子。

這個原話是可以靈活理解的,就看我們怎么定義鴨子的行為,我們可以說,能浮在水上游的,黃色的,可愛的就是鴨子,那么,圖片中的大黃鴨,它就是一只鴨子!

這就是所謂的 Duck Typing,

它只關心事物的外部行為而非內部結構。它并不關心你這只鴨子是長肉的還是充氣的。

在編程中,也常常用這種方式來描述事物。那么不同的編程語言中,Duck Typing 是怎么樣實現的呢?

1. Python 中的 Duck Typing

先看一個函數:

def download(fetcher):

return fetcher.get("http://xxx");

有一個 download 函數,傳過來一個 fetcher 參數,fetcher 是可以獲取一個 url 鏈接的資源的。

這個 fetcher 就是一個 Duck Typing 的對象,使用者約定好這個 fetcher 會有一個 get 函數就可以了。

顯然這個 download 函數會有以下問題:

運行時才知道傳入的 fetcher 有沒有 get 函數。那么站在 download 函數的使用者的角度上看,我怎么知道需要給 fetcher 實現 get 方法呢?我不可能去閱讀 download 函數的代碼,實際情況中,可能 download 函數的代碼很長,可能 fetcher 不只要實現 get 方法,還有其它方法需要實現。通常這種情況需要通過加注釋來說明。

2. C++ 中的 Duck Typing

C++ 不是動態語言,但是它也能支持 Duck Typing,它是通過模板來支持的。

示例代碼:

template

string download(const F& fetcher){

return fetcher.get("http://xxxx")

}

這段代碼與 Python 的實現方法類似,這個 fetcher 隨便什么類型都可以,只要實現一個 get 方法,就能通過編譯。

那么這種實現方法有什么缺點呢,就是,編譯時,才知道傳入的 fetcher 有沒有 get 方法。

但它比 python 好一點了,python 是運行時才知道,C++ 是編譯時就知道。

同樣,這種情況,還是需要注釋來說明。

3. Java 中的類似代碼

Java 沒有 Duck Typing,它只有類似的代碼。Java 的 duck typing :

String download(F fetcher){

return fetcher.get("http://xxxx")

}

它同樣也用了模板類型。模板 F 必須 extends FetcherInterface ,有了這個限定,就能逼著 download 函數的使用者對 fetcher 實現 get 方法,它解決了需要注釋來說明的缺點。

傳入的參數必須實現 FetcherInterface 接口,就沒有運行時發現錯誤,編譯時發現錯誤的問題。

但是,它嚴格上來說不是 Duck Typing 。

如果 download 函數只依賴 fetcher 的 get 方法,而 FetcherInterface 接口必須要實現除 get 方法以外,還有其它方法,那么也要一一實現,非常不靈活。

4. Go 中的 Duck Typing

在 Java 的 Duck Typing 類似代碼中,如果 fetcher 參數需要同時實現兩個或以上的接口方法時,Java 是沒有辦法做到的。但 Go 語言可以做到。

type Fetcher interface {

Get(url string) string

}

type Saver interface {

Save(content string)

}

type FetcherAndSaver interface {

Fetcher

Saver

}

func download(f Fetcher) string {

return f.Get("http://xxxx")

}

func save(f saver) {

f.Save("some thing")

}

func downloadAndSave(f FetcherAndSaver) {

content := f.Get("http://xxxx")

f.Save(content)

}

# 實現者

type MyFetcherAndSaver struct {

}

func (f MyFetcherAndSaver) Get(url string) string {

...

}

func (f MyFetcherAndSaver) Save(content string) {

...

}

func main() {

f := MyFetcherAndSaver{}

download(f)

save(f)

downloadAndSave(f)

}

這里定義了三個接口,只要有 Get 方法的就是 Fetcher,只要有 Save 方法的就是 Saver,同時有 Get 方法和 Save 方法就是 FetcherAndSaver 。

實現者 MyFetcherAndSaver 并不需要聲明它實現了哪些接口,只要它有相關接口的所定義的方法,那么它的實例,就即能作為 Fetcher 接口來使用,又能作為 Saver 接口來使用,也能作為 FetcherAndSaver 接口來使用。

Go 的實現方法相對比較靈活,又不失類型檢查。總的來說,特點有:

即能同時實現多個接口

又具有 python , C++ 的 Duck Typing 靈活性

又具有 java 的類型檢查。

本文完~

總結

以上是生活随笔為你收集整理的duck typing java_编程语言中的鸭子类型 Duck Typing的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。