この記事はから来ている:CSDNのブログ
おかげで著者:fengfengdiandia
オリジナルを参照してください:ゴー・インタフェースを
ゴー言語は、「伝統的な」オブジェクト指向のプログラミング言語ではありません:それは内部でない类
と继承
概念。
しかし囲碁言語は非常に柔軟性がある接口
という概念を、私たちはそのを通じて多くのことを達成することができます面向对象
機能。
接口
それは定義し 方法的集合
、これらの方法は 不包含实现代码
、彼らは 抽象的
、インタフェースもあります 不能包含变量
。
定義フォーマット
インターフェースの一般的なフォーマットの定義:
ナメルインターフェイスを入力{ 方法1(param_list)return_type 方法2(param_list)return_type ... }
上記は、 Namer
インターフェイスタイプです。
しかし、移動に 接口
値、があり 接口类型
変数または 接口值
:var ai Namer
、ai
それは multiword
その値は、データ構造 nil
。
それは本質的だ 指针
正確にいえ、同じものではありません。値はインターフェイスへのポインタである非法的
エラーコードになります。
类型
(このような構造として)実施される方法インタフェースメソッドセット達成 Namer
インタフェースタイプは変数に割り当てることができ ai
、インターフェイス・メソッドへのメソッドテーブルポインタポイントが実装されています。
インタフェースの実装型は、インターフェイスメソッドの実装に加えて、あなたはまた、独自のメソッドを持つことができます。
メインパッケージ インポート"FMT" 入力シェイパーインターフェース{ エリア()のfloat64 //境界()のfloat64 } 入力長方形構造体{ 長さのfloat64 幅のfloat64 } //实现シェイパー接口中的方法 FUNC(R *矩形)領域()のfloat64 { リターンr.length * r.width } //セット是属于長方形自己的方法 FUNC(R *長方形)セット(のfloat64 Wリットルのfloat64、){ r.length =リットル r.width = W } FUNCメイン(){ RECT。 =新しい(長方形) rect.Set(2、3) areaIntf:=シェイパー(RECT) fmt.Printf( "RECTエリアを有する:%F \ n"、areaIntf.Area()) }
削除した場合 、コメントをので、あなたは、以下のコンパイル時にエラーが発生します 実装されていない 方法を。Shaper
Perimeter() float64
Rectangle
Perimeter()
cannot convert rect (type *Rectangle) to type Shaper: *Rectangle does not implement Shaper (missing Perimeter method)
ポリモーフィズム
図1に示すように、複数種類の同じインタフェースを実装することができます。
図2に示すように、インターフェイスのタイプの複数を達成することができます。
ここでは、タイプを追加し Triangle
、それがまたとして実装され、 Shaper
インターフェース。
パッケージメイン インポート"FMT" 入力シェイパーインターフェース{ エリア()のfloat64 //境界()のfloat64 } // ====長方形==== タイプ長方形構造体{ 長さのfloat64 幅のfloat64 } //实现シェイパー接口中的方法 FUNC (R *矩形)領域()のfloat64 { 戻りr.length * r.width } //セット是属于長方形自己的方法 FUNC(R *長方形)セット(リットルのfloat64、Wのfloat64){ r.length =リットル R。幅= W } // ====長方形エンド==== // ====トライアングル==== 型トライアングル構造体{ 底のfloat64 ハイトのfloat64 } FUNC(T *三角)エリア()のfloat64 { 戻りt.bottom * t.hight / 2 } FUNC(T *三角)セット(B用のfloat64、時間のfloat64){ t.bottom = B t.hight = H } // ====トライアングルエンド==== メイン(){FUNC RECT =新しい(長方形) rect.Set(2、3) areaIntf:=シェイパー(RECT) fmt.Printf(「RECTエリアを有する:%F \ N」、areaIntf.Area()) 三角形:=新しい(三角) triangle.Set(2、3) areaIntf =シェイパー(三角形) fmt.Printf( "三角形面積有する:%F \ n"は、areaIntf.Areaを( )) }
柔軟性
インターフェイスの定義は、より柔軟です。
すべてのタイプの実装インタフェースのメソッドは、それがこのインタフェースを実装する限り、異なるインターフェイスのタイプ、及びパッケージに仮定する。
今、私たちはなり Shaper
に定義し shaper 包
、次、 Rectangle
および Triangle
上の定義は test 包
次の:
[ルート@ SRC]#ツリー ├──テスト │└──test.go ├──main.go └──シェイパー └──shaper.go
shaper.go
パッケージ整形 型シェイパーインタフェース{ エリア()のfloat64 }
test.go
パッケージテスト // ====長方形==== タイプ長方形構造体{ 長さのfloat64 幅のfloat64 } //实现シェイパー接口的方法 FUNC(R *矩形)領域()のfloat64 { 戻りr.length * r.width } / /セット是属于長方形自己的方法 FUNC(R *長方形)セット(のfloat64 W Lのfloat64、){ r.length =リットル = W r.width } // ====長方形エンド==== // == ==トライアングル==== 型トライアングル構造体{ 底のfloat64 ハイトのfloat64 } FUNC(T *三角)エリア()のfloat64 { 戻りt.bottom * t.hight / 2 } FUNC(T *三角)セット(B用のfloat64、H float64){ t.bottom = B t.hight = H } // ====トライアングルエンド==== // main.go メインパッケージ のインポート( "FMT" "シェーパ" "試験" ) {main()のFUNC RECT =新しい(test.Rectangle) rect.Setを( 2、3) areaIntf:= shaper.Shaper(RECT) fmt.Printf( "RECTエリアを有する:%N \ F"、areaIntf.Area()) 三角形:新しい(test.Triangle)= triangle.Set(2、 3) areaIntf = shaper.Shaper(三角形) fmt.Printf( "三角形の面積を有する:%F \ n"、areaIntf.Area()) }
今実行して main.go
その結果、フンフン、問題はないが、見て^ _ ^
The rect has area: 6.000000
The triangle has area: 3.000000
ネストインタフェース
インタフェースは同じインタフェースを含む外側層中に埋め込まれ、これらの方法のインターフェイスに直接対応する一つまたは複数の他のインターフェイスを含んでもよいです。
例えば、インタフェースは File
含ま ReadWrite
と Lock
、すべての方法は、また、追加有する Close()
方法。
入力読み書きインターフェース{ 読む(緩衝液B)ブール ライト(緩衝液B)BOOL } 型ロックインターフェース{ ロック() ロック解除() } 型ファイルインターフェイス{ 読み書き ロック クローズ() }
型アサーション
私は、構造体の型を書いた場合は MyFile
、上記を達成するため File
のインタフェースを、どのように私は知って MyFile
実装するかどうか File
、それへのインターフェイスを?
通常、我々は使用 类型断言
いくつかの点でテストを varI
の種類含めるかどうか T
の値を:
Vの場合、[OK]:= VARI(T); OK {//チェック型アサーション 工程(v)の 戻り } //バリが型Tではありません
あなたがいる場合 v
している varI
の型に変換し T
た値ok
になり true
、それ以外の場合は、 v
の一種で T
、ゼロ値ok
です false
。
// main.go
以下のための主要なパッケージ変更 のインポート"FMT" タイプstruct {}でMyFileの FUNC(M * MyFileの)リード(){BOOL fmt.Printf( "読む()\ N-") をtrueに復帰 } // ... 私はここに達成している//ましょうと言います書き込み()、ロック()、ロック解除() とClose()メソッド FUNCメイン(){ マイ:=新新(MyFileの) fIntf:ファイル=(マイ) //ここで見て、こちらをご覧 Vの場合、[OK]:= fIntf。 (* MyFileの); OK { v.Read() } }
出力は次のようになります。リード()
複数のタイプは、フロントと同じインターフェース、実装している場合 areaIntf
、それをテストする方法を、?
そして、使用 type-switch
裁判官に。
型スイッチタイプの判断
スイッチT:= areaIntf(タイプ){ ケース*四角形: //何かの ケース*トライアングル: //何かの デフォルト: //何かを行います }