Golangオブジェクト指向プログラミング
*カタログ
00Golang言語オブジェクト指向プログラミング命令
01フィールド、属性
02メソッド
03オブジェクト指向プログラミング
04ファクトリモード
05オブジェクト指向プログラミングのアイデア*
00Golang言語のオブジェクト指向プログラミング命令
-
Golangはオブジェクト指向プログラミング(OOP)もサポートしていますが、これは従来のオブジェクト指向プログラミングとは異なり、純粋なオブジェクト指向言語ではありません。したがって、Golangはオブジェクト指向プログラミング機能をサポートしていると言った方が正確です。
-
Golangにはクラスがありません。Go言語の構造は他のプログラミング言語のクラスと同じステータスです。Golangは構造体に基づいてOOP機能を実装していることが理解できます。
-
Golangオブジェクト指向プログラミングは非常に簡潔で、従来のOOP言語の継承、メソッドのオーバーロード、コンストラクタとデストラクタを削除し、このポインタを非表示にします。
-
Golangには、オブジェクト指向プログラミングの継承、カプセル化、およびポリモーフィズムの特性がありますが、実装は、継承などの他のOOP言語とは異なります。Golangにはextendsキーワードがなく、継承は匿名フィールドを介して実現されます。
-
Golangオブジェクト指向(OOP)は非常にエレガントで、OOP自体は、インターフェイス(インターフェイス)の関連付け、低結合、および非常に柔軟な方法で、言語型システム(型システム)の一部です。言い換えれば、インターフェース指向プログラミングはGolangの非常に重要な機能です。
構造と構造変数の違いと関係(インスタンス)
-
構造はカスタムデータ型であり、物事のクラスを表します
-
構造変数(インスタンス)は具体的で実際のものであり、具体的な変数を表します
構造を宣言する方法
タイプ構造体名構造体{ フィールド1タイプ フィールド2タイプ ... }
犬の構造を定義する
type Dog struct { 名前文字列 年齢int64 色文字列}
01フィールド、属性
-
概念または名前の観点から:構造フィールド=属性=フィールド
-
フィールドは構造のコンポーネントであり、通常は基本データ型、配列ですが、参照型でもあります。
メモと詳細
-
フィールド宣言の構文は変数の構文と同じです。例:フィールド名フィールドタイプ
-
フィールドのタイプは、基本タイプ、配列、または参照タイプです。
-
構造変数を作成した後、フィールドに値が割り当てられていない場合、それはゼロ値(デフォルト値)に対応し、ルールは前のルールと同じです。
-
スライスを使用して確認してください:p1.slice1 = make([] int、10)
-
マップを使用して確認してください:p1.map1 = make(map [string] string)
-
ブール型はfalse、値は0、文字列は「」です。
-
配列型のデフォルト値は、その要素型に関連しています。たとえば、score [3] intは[0,0、0]です。
-
ポインタ、スライス、およびマップのゼロ値はすべてnilです。つまり、スペースはまだ割り当てられていません。
-
-
異なる構造変数のフィールドは独立しており、相互に影響を与えることはなく、構造は値型です。
構造変数を作成し、構造フィールドにアクセスします
var dd Dogvar dd Dog = Person {"小花"、4、 "red"} var dd * Dog = new(Dog) (* dd).Name = "小花" dd.Name = "小花" var dd * Dog =&Dog {"小花"、4、 "red"} var dd * Dog =&Dog {} (* dd).Name = "小花" dd.Name = "小花"
説明:
1) 3番目と4番目のメソッドは構造体ポインターを返します。2) 構造体ポインタがフィールドにアクセスするための標準的な方法は次のとおりです。(*構造体ポインタ)。 (* person).Name = "tom"などのフィールド名3)ただし、goは簡略化されており 、構造体ポインタもサポートしています。フィールド person.Name = "tom"などの名。3) goコンパイラの最下層がperson.Name(* person).Nameを変換しました。
構造物の使用に関する注意事項と詳細
-
構造のすべてのフィールドはメモリ内で連続しています
-
構造体はユーザーが個別に定義する型であり、他の型と変換する場合は、まったく同じフィールド(名前、番号、型)が必要です。
-
構造はタイプによって再定義されます(エイリアシングと同等)。Golangはそれを新しいデータタイプと見なしますが、相互に転送するように強制することができます。
-
構造体の各フィールドにタグを書き込むことができ、リフレクションメカニズムを介してタグを取得できます。一般的な使用シナリオは、シリアル化と逆シリアル化です。
02メソッド
Golangのメソッドは、指定されたデータ型(つまり、指定されたデータ型にバインドされている)で機能するため、カスタム型には構造体だけでなくメソッドも含めることができます。
メソッド宣言と呼び出し
タイプ Astruct { Num int} func(a A)test(){ fmt.Println(a.Num) }
説明
-
func(a A)test(本はA構造にメソッドがあることを示しています。メソッドはtestと呼ばれます
-
(aA)は、テストメソッドがタイプAにバインドされていることを反映しています
package mainimport( "fmt")type Person struct { Name string} func(P Person)test({ fmt.Println( "test((name ="、p.Name)func main(){var p Personp.Name = " tom " p.test()// Callメソッド } // 1)テストメソッドはPersonタイプにバインドされています // 2)テストメソッドはPersonタイプの変数によってのみ呼び出すことができ、直接呼び出すことはできません。また、他のタイプの変数を使用して // func(p Person)test().... pを呼び出すことはできません。pはどのPerson変数が呼び出されるかを表し、このpはそのコピーであり、多くの場合、関数の受け渡しに似ています。 // 4)名前pはプログラマーによって指定され、固定されていません。たとえば、人に変更できます。
メソッド呼び出しとパラメータ転送メカニズムの原理
-
変数を介してメソッドを呼び出す場合、呼び出しメカニズムは関数のメカニズムと同じです。
-
違いは、変数がメソッドを呼び出すと、変数自体もパラメーターとしてメソッドに渡されることです(変数が値型の場合は値がコピーされ、変数が参照型の場合はアドレスコピーされます)
メソッドのメモと詳細
-
構造型は値型です。メソッド呼び出しでは、値型の転送メカニズムに準拠しています。これは、値コピー転送メソッドです。
-
プログラマーがメソッド内の構造体変数の値を変更したい場合は、構造体ポインターで処理できます。
-
Golangのメソッドは、指定されたデータ型に作用します(つまり、指定されたデータ型にバインドします)。したがって、カスタムタイプは、int、float32などの構造体だけでなく、メソッドを持つことができます。
-
メソッドのアクセススコープを制御するためのルールは、関数のルールと同じです。メソッド名の最初の文字は小文字であり、このパッケージでのみアクセスできます。メソッドの最初の文字は大文字で表記され、このパッケージおよび他のパッケージでアクセスできます。
-
型がString()メソッドを実装している場合、fimt.PrintInはデフォルトでこの変数のString()を呼び出して出力します
型バインディングでの値のコピーとアドレスのコピー
-
呼び出し形式に関係なく、実際の決定は、メソッドがバインドされているタイプに応じて、値のコピーまたはアドレスのコピーです。
-
(p Person)などの合計値型の場合は値のコピーであり、(p * Person)などのポインタ型の場合はアドレスコピーです。
-
アドレスコピーは、バインディングタイプの属性を変更できます
03オブジェクト指向プログラミング
ステップ
-
構造を宣言(定義)し、構造の名前を決定します
-
構造体のフィールドを書き込む
-
構造の書き方
構造変数を作成するときにフィールド値を指定する
var stu1 = Stu {"小明"、19} var stu3 = Stu { 名前: "ジャック"、 年齢:20、 } var stu5 * stu =&stu { "小王"、29} var stu7 =&stu {名前: "小リー」、 年齢:49、 }
04ファクトリーモード
Golangの構造にはコンストラクターがなく、通常、ファクトリパターンを使用してこの問題を解決できます。
構造体のStudentの最初の文字Sは大文字です。他のパッケージ(メインパッケージなど)でStudentのインスタンスを作成し、モデルパッケージをインポートする場合は、の変数(インスタンス)を直接作成できます。学生の構造。しかし、ここで問題が発生します。タイプstudent structのように、最初の文字が小文字の場合は機能しません。実行する方法?解決するファクトリモデル。
ファクトリパターンを使用して、パッケージ全体で構造インスタンス(変数)を作成します
タイプ studentstruct {名前stringscorefloat64) fune Newstudent(n string、s float64)* student {return&student { 名前:n、 スコア:s、 }
05オブジェクト指向プログラミングのアイデア
概要
以前に構造を定義するとき、実際には、物事のクラスの共通の属性(フィールド)と動作(メソッド)を抽出して、物理モデル(構造)を形成します。問題を研究するこの方法は、抽象化と呼ばれます。
カプセル化
Golangには、オブジェクト指向プログラミングの継承、カプセル化、およびポリモーフィズムの機能がまだありますが、実装方法は他のOOP言語とは異なります。
カプセル化とは、抽象化されたフィールドとフィールドに対する操作をカプセル化することです。データは内部で保護され、プログラムの他のパッケージは、許可された操作(メソッド)を介してのみフィールドを操作できます。
カプセル化の理解と利点
-
実装の詳細を非表示にする
-
安全性と合理性を確保するためにデータを検証することができます(年齢)
カプセル化を反映する方法
-
構造内の属性をカプセル化します
-
この方法により、パッケージはカプセル化を実現します
カプセル化の実現手順
-
構造とフィールド(属性)の最初の文字を小文字にします(プライベートと同様に、エクスポートできません。他のパッケージは使用できません)
-
構造が配置されているパッケージに、最初の文字を大文字にして、ファクトリモード機能を提供します。コンストラクターに似ています
-
属性を判断して割り当てるために、頭文字が大文字のSetメソッド(他の言語のpublicと同様)を提供します
-
属性を取得するために、頭文字が大文字のGetメソッド(他の言語のpublicと同様)を提供します
特記事項:
Golang開発では、カプセル化に特別な重点は置かれていません。これはJavaとは異なり、Golang自体がオブジェクト指向機能を単純化します。
type person struct { Name string age int} func NewPerson(name string)* person {return&person { Name:name、 } } func(p * person)setAge(age int){if age> 0 && age <150 { p。 age = age } else { fmt.Print1n( "年龄范围承确..") } } func(p * person)GetAge()int {return p.age }
継承
継承はコードの再利用を解決し、プログラミングを人間の思考に近づけることができます。
複数の構造が同じプロパティ(フィールド)とメソッドを持っている場合、構造はこれらの構造から抽象化でき、これらの同じプロパティとメソッドを構造で定義できます。
ネストされた匿名構造の基本構文
type Goods struct { Name stringPrice int} type Book struct { Goods Writer string}
継承の詳細な議論
-
構造体は、ネストされた匿名構造体のすべてのフィールドとメソッドを使用できます。つまり、最初の文字が大文字または小文字のフィールドとメソッドを使用できます。
-
匿名構造のフィールドアクセスを簡素化できます。
bAName = "tom" bAage = 19b.A.Sayok() bAhello() b.Name = "smith" b.age = 20b.sayok() b.hello()
-
構造体と匿名構造体が同じフィールドまたはメソッドを持っている場合、コンパイラは最近傍アクセスの原則を使用します。匿名構造体のフィールドとメソッドにアクセスする場合は、匿名構造体の名前で区別できます。
bAage = 19
-
構造体には2つ(またはそれ以上)の匿名構造体が埋め込まれています。たとえば、2つの匿名構造体には同じフィールドとメソッドがあります(同時に、構造体自体には同じ名前のフィールドとメソッドがありません)。アクセスするときは、明示的にアクセスする必要があります。匿名構造体の名前を指定します。指定しない場合は、エラーをコンパイルします。
-
構造体が名前付き構造体でネストされている場合、このモードは組み合わせです。組み合わせ関係の場合、結合された構造体のフィールドまたはメソッドにアクセスするときは、構造体の名前を指定する必要があります。
タイプ Dstruct iaA }
-
匿名構造がネストされた後、構造変数(インスタンス)を作成するときに、各匿名構造フィールドの値を直接指定することもできます。
type Goods struct { Name string Price float64} type Brand struct { Name string Address string} type TV struct { Goods Brand } type TV2 struct { * Goods * Brand } tv:= TV {Goods {"electric视001"、900.99}、Brand {"Haier"、 "Shandong"}、} tv2:= TV { Goods { 価格:88.99、 名前: "electric视ee2" }、 ブランド{ 名前: "Sharp"、 住所: "Beijing"、 }、 } tv3:= TV2 {&Goodsf {"TV03"、7000.99}、&Brand {"Skyworth"、 "Henan"}} tv4:= TV2 { &商品{ 名前: "TV 4"、 価格:9eee.99、 } &Brand { 名前: "Changhong"、 住所: "Sichuan"、 }、 }
多重継承
構造体が複数の匿名構造体でネストされている場合、構造体はネストされた匿名構造体のフィールドとメソッドに直接アクセスできるため、多重継承が実現されます。
コードを単純化するために、多重継承の使用はできるだけ避けることをお勧めします。
インターフェース
Golangのポリモーフィズムは、主にインターフェイスを介して反映されます
インターフェイスタイプは一連のメソッドを定義できますが、これらを実装する必要はありません。また、インターフェースに変数を含めることはできません。特定のカスタムタイプを使用する場合、これらのメソッドは特定の状況に応じて記述(実装)されます。
タイプUsbインターフェイス{ Start() Stop() }
-
インターフェイスのすべてのメソッドにはメソッド本体がありません。つまり、インターフェイスのメソッドは実装されていないメソッドです。インターフェースは、プログラム設計のポリモーフィズムと高い凝集度および低い結合度のアイデアを具体化します。
-
Golangのインターフェースは明示的に実装する必要はありません。変数にインターフェイスタイプのすべてのメソッドが含まれている限り、この変数はインターフェイスを実装します。したがって、Golangに実装するようなキーワードはありません
メモと詳細
-
インターフェイス自体はインスタンスを作成できませんが、インターフェイスを実装するカスタムタイプの変数(インスタンス)を指すことはできます
-
インターフェイスのすべてのメソッドにはメソッド本体がありません。つまり、これらはすべて実装されていないメソッドです。
-
Golangでは、カスタム型はインターフェイスのすべてのメソッドを実装する必要があります。このカスタム型はインターフェイスを実装すると言います。
-
カスタムタイプは、特定のインターフェイスを実装している場合にのみ、カスタムタイプのインスタンス(変数)をインターフェイスタイプに割り当てることができます。
-
カスタムデータ型である限り、構造型だけでなく、インターフェイスを実装できます。
-
カスタムタイプは複数のインターフェースを実装できます
-
Golangインターフェースに変数を含めることはできません
-
インターフェイス(Aインターフェイスなど)は、他の複数のインターフェイス(BおよびCインターフェイスなど)を継承できます。この時点で、Aインターフェイスを実装する場合は、BおよびCインターフェイスのすべてのメソッドも実装する必要があります。
-
インターフェイスタイプはデフォルトでポインタ(参照タイプ)です。インターフェイスを初期化せずに使用すると、nilが出力されます。
-
空のインターフェイスインターフェイス}にはメソッドがないため、すべてのタイプで空のインターフェイスが実装されます。つまり、空のインターフェイスに任意の変数を割り当てることができます。
継承とインターフェースの違い
-
A構造体がB構造体を継承する場合、A構造体はB構造体のフィールドとメソッドを自動的に継承し、直接使用できます。
-
A構造体がその機能を拡張する必要があり、継承関係を破壊したくない場合は、インターフェースを実装できます。したがって、インターフェースの実装は継承メカニズムの補足であると考えることができます。
インターフェイスの実装は、継承の補足と見なすことができます
インターフェイスと継承はさまざまな問題を解決します
-
継承の価値は、主にコードの再利用性と保守性を解決することです。
-
インターフェイスの価値は主に、設計、さまざまな仕様(メソッド)の設計、および他のカスタムタイプにこれらのメソッドを実装させることにあります。
-
インターフェイスは継承よりも柔軟性があります
-
インターフェイスは継承よりも柔軟性があります。
-
継承はis-a関係を満たすことです
-
インターフェースは、同様の関係を満たす必要があるだけです
-
-
インターフェイスは、ある程度のコードデカップリングを実現します
ポリモーフィズム
変数(インスタンス)には多くの形式があります。オブジェクト指向の3番目の主要な機能であるGo言語では、ポリモーフィズムはインターフェースを介して実現されます。統一されたインターフェースに従って、さまざまな実装を呼び出すことができます。このとき、インターフェース変数は別の形式になります。
-
多形パラメータ
-
ポリモーフィック配列
タイプアサーション
タイプアサーション。インターフェイスは一般的なタイプであるため、特定のタイプがわかりません。特定のタイプに変換する場合は、タイプアサーションを使用する必要があります。
var x interface {} var b2 float32 = 1.1x = b2 y:= x。(float32) fmt.Printf( "yのタイプはランプ値=%v"、y、y)
タイプアサーションを作成するときに、タイプが一致しない場合はパニックが報告されます。したがって、タイプアサーションを作成するときは、元の空のインターフェイスがアサーションされたタイプを指していることを確認してください。
var x interface {} var b2 float32 = 2.1 x = b2if y、ok:= x。(float32); ok { fmt.Println( "convert success") fmt.Printf( "yのタイプは%Tで、値はis =%v "、y、y) } else { fmt.Print1n(" convert fai1 ") } fmt.Print1n("実行を続行... ")